嚴格次小生成樹

2022-02-05 13:42:27 字數 1751 閱讀 2183

顧名思義。

生成樹,邊權和嚴格小於最小生成樹

一定和最小生成樹有關係。

實際上,有

結論1:嚴格次小生成樹只在最小生成樹上改動一條邊

證明:改動一條邊有意義的話,必然改完這條邊,總和變大。

那麼這至少是嚴格次小生成樹的最大值。再改一條也沒有意義。

結論2:改動的那條邊w,一定是新加入的那條邊覆蓋的樹鏈的最大值或者嚴格次大值。

證明:w比最大值大的話,一定扔掉這個最大值

相等的話,一定扔掉嚴格次大值。

如果不存在嚴格次大值,那麼不可能。也符合「嚴格」的題意。

kruscal跑mst

列舉剩下沒有加入的邊,要求出這條鏈上的最大值和嚴格次大值

可以倍增,樹剖,lct等等。

倍增顯然最優。

【模板】嚴格次小生成樹[bjwc2010]

#include#define il inline

#define reg register int

#define numb (ch^'0')

#define int long long

using

namespace

std;

typedef

long

long

ll;il

void rd(int &x)

namespace

miracle

}bian[m];

intff[n];

int fin(int

x)int fa[n][20],mx[n][20],cmx[n][20

];ll sum;

struct

edgee[

2*n];

inthd[n],cnt;

void add(int x,int y,int

z)int

dep[n];

ll ans;

void dfs(int x,intd)}

int query(int x,int y,ll z)

}if(x==y)

for(reg j=19;j>=0;--j)

}int j=0

;

if(mx[x][j]!=z) big=max(big,mx[x][j]);

else big=max(big,cmx[x][j]);

if(mx[y][j]!=z) big=max(big,mx[y][j]);

else big=max(big,cmx[y][j]);

return z-big;

}int

main()

for(reg i=1;i<=n;++i) ff[i]=i;

sort(bian+1,bian+m+1

);

for(reg i=1;i<=m;++i)

}//cout<<" sum "; dfs(

1,1);

for(reg j=1;j<=19;++j)

}ans=0x3f3f3f3f3f3f3f3f

;

for(reg i=1;i<=m;++i)

}printf(

"%lld

",ans);

return0;

}}signed main()

/*author: *miracle*

date: 2018/12/19 14:36:23

*/

總結 嚴格 次小生成樹

首先需要了解什麼是最小生成樹,還要知道什麼是倍增 求lca 上面的東西如果了解了,就可以開始進入學習的路途了 用不是最小生成樹上的邊去更新答案.對於每乙個倍增跳上去的,要維護兩個東西 我們考慮一下對於每一條邊 不在最小生成樹上 如果要把它加入答案,如何更新?mst 路徑最大值 邊權.然後這個東西就可...

嚴格次小生成樹學習筆記

嚴格次小生成樹,顧名思義,就是在聯通圖上選擇一些邊構成一棵樹,使這棵樹邊權和嚴格次小。要求嚴格次小生成樹,我們就要先求出最小生成樹 prim 和 kruskal 等演算法都可以,我用的是 kruskal 在求最小生成樹的過程中,還要給每條使用過的邊打乙個標記,如下 inline void krusk...

瘋子的演算法總結11 次小生成樹 嚴格次小生成樹

首先,我這一題的思路是倍增lca kruskal 首先,kruskal求最小生成樹 不會的戳這裡 求次小生成樹 倍增 lca 關鍵在於次小生成樹怎麼求 問自己一些問題 怎麼求不嚴格次小生成樹 不嚴格次小生成樹為什麼不嚴格 方法每次選擇u v之間的邊,前提是最小生成樹上不存在的邊,添邊之後刪去較短邊,...