次小生成樹 Tree(倍增)

2021-08-21 04:42:53 字數 2910 閱讀 8493

時間限制: 1000 ms 記憶體限制: 524288 kb

小 c 最近學了很多最小生成樹的演算法,prim 演算法、kurskal 演算法、消圈演算法等等。 正當小 c 洋洋得意之時,小 p 又來潑小 c 冷水了。小 p 說,讓小 c 求出乙個無向圖的次小生成樹,而且這個次小生成樹還得是嚴格次小的,也就是說: 如果最小生成樹選擇的邊集是 em,嚴格次小生成樹選擇的邊集是 es,那麼需要滿足:(value(e) 表示邊 e的權值) ∑e

∈emv

alue

(e)<∑e

∈esv

alue

(e) ∑e∈

emva

lue(

e)

<∑e

∈esv

alue

(e

)這下小 c 蒙了,他找到了你,希望你幫他解決這個問題。

第一行包含兩個整數

n n

和m' role="presentation" style="position: relative;">m

m,表示無向圖的點數與邊數。 接下來

m m

行,每行 3個數

x' role="presentation" style="position: relative;">xxy

y

z' role="presentation" style="position: relative;">z

z表示,點

x x

和點y' role="presentation" style="position: relative;">y

y之間有一條邊,邊的權值為

z z

。包含一行,僅乙個數,表示嚴格次小生成樹的邊權和。(資料保證必定存在嚴格次小生成樹)

輸入樣例

5 6

1 2 1

1 3 2

2 4 3

3 5 4

3 4 3

4 5 6

輸出樣例
11
資料中無向圖無自環;

50% 的資料n≤

2000,m

≤3000' role="presentation" style="position: relative;">n≤2

000,m≤

3000n≤

2000,m

≤3000;

80% 的資料n≤

50000,m

≤100

000 n≤50

000,m≤

100000

; 100% 的資料n≤

100000,m

≤300

000 n

≤100

000,m≤

300000

,邊權值非負且不超過 109109

。' role="presentation" style="position: relative;">

' role="presentation" style="position: relative;">

' role="presentation" style="position: relative;">

' role="presentation" style="position: relative;">

' role="presentation" style="position: relative;">

次小生成樹的一般解法?

先建立最小生成樹,列舉加入非樹邊,求環上最大值,然後減去這條邊就是答案。由於我們不知道環上的最值是否和非樹邊相等,所以我們還需要維護乙個次大值。

其實演算法很好理解,這裡有乙個問題,筆者似乎無法解答。次大生成樹似乎不滿足kruskal的貪心性質?假如我們把非樹邊排序,加入最小邊不一定是次小生成樹。希望有人可以解答。

估計是我kruskal太菜了。

關於**實現:維護次大值似乎沒有什麼好的方法,寫得很麻煩。然後好久沒有倍增了,倍增求還要特判

u u

,v' role="presentation" style="position: relative;">v

v是不是lc

a lca

。code:

#include

#include

#include

#include

using

namespace

std;

struct lxyeg[600005];

struct data

}yyy;

int n,m,t,cnt=-1,head[100005],dep[100005];

long

long ans,rans=0x7f7f7f7f7f7f7f7f;

int f[100005][18],s[100005][18],fa[100005][18];

bool vis[100005];

void add(int op,int ed,int len)

void prim()

while(!d.empty()&&vis[d.top().id]==1) d.pop();

}}void woc(int x,int y,int p)

if(p==fi&&si!=-1) rans=min(rans,ans+p-si);

else

if(p!=fi) rans=min(rans,ans+p-fi);

}int main()

prim();

for(int i=1;i<=17;i++)

for(int j=1;j<=n;j++)

for(int i=1;i<=n;i++)

for(int j=head[i];j!=-1;j=eg[j].next)

printf("%lld",rans);

}

次小生成樹Tree

小c最近學了很多最小生成樹的演算法,prim演算法 kurskal演算法 消圈演算法等等。正當小c洋洋得意之時,小p又來潑小c冷水了。小p說,讓小c求出乙個無向圖的次小生成樹,而且這個次小生成樹還得是嚴格次小的,也就是說 如果最小生成樹選擇的邊集是em,嚴格次小生成樹選擇的邊集是es,那麼需要滿足 ...

次小生成樹 倍增 LCA

給乙個n個點m條邊 n 100000,m 300000 的無向圖,求它的嚴格次小生成樹。資料範圍很大,o n 2 的演算法顯然是不行的。由於最小生成樹是一棵樹,求任意兩點路徑上的最大 次大邊就成為了經典的lca問題。因此,我們得到了下面的演算法 1 把邊按權值從小到大排序,時間複雜度為o mlogm...

次小生成樹(倍增 lca)

題目描述給定一張 n 個點 m 條邊的無向圖,求無向圖的嚴格次小生成樹。設最小生成樹的邊權之和為sum,嚴格次小生成樹就是指邊權之和大於sum的生成樹中最小的乙個。輸入格式 第一行包含兩個整數n和m。接下來m行,每行包含三個整數x,y,z,表示點x和點y之前存在一條邊,邊的權值為z。輸出格式 包含一...