最小生成樹的Boruvka演算法

2021-09-13 01:30:02 字數 2132 閱讀 1057

偶然得知了居然還有這種神奇的演算法,qwq。

老年選手覺得很有意思,所以頹廢地學了一下……

簡單來說,它就是乙個多路增廣的kruskal。

kruskal為什麼是對的它就為什麼是對的

它的流程是這樣的:

1.對於每個連通塊,找到一條由它內部的點連向其它連通塊的最小邊。

2.把這些最小邊加入進去。(注意加入的時候要判它是不是連線了兩個不同連通塊)

3.如果已經放進去了n-1條邊則退出,不然則繼續。

根據啟發式合併的思想,顯然它只要做o(log n)次。每次加邊的複雜度是o(m),

合併的複雜度是o(n),那麼總複雜度就是o((m+n) log n)。

然而它好像比kruskal不知道麻煩到**去了。聰明的讀者紛紛表示:要它有什麼用???

shivering太弱了,所以也不知道欸。於是詢問了教我這個演算法的巨佬,巨佬表示:可以拿來出題啊!出好多好多題啊!

……orz,orz。反正orz就完事了……

顯然不是出最小生成樹裸題用的。

我們發現,它唯一的難點在於如何給每個連通塊找到它連出去的最小邊。

暴力是o(m),但我們會發現,有許許多多的題目,邊的數目非常大,而邊權又有某種規律。

這時候,就可以套上各種各樣的資料結構/dp/分治來維護它了。

採用boruvka以後,基本就變成了另一道全新的題,愛出什麼出什麼。

仔細思考,prim直接n^2,kruskal初始就要對邊排序,都不適合套上太多東西。

將最小生成樹分解為找最小邊的問題,正是boruvka最有趣的地方。

例題:luogup3369 最小生成樹裸題

記邊時最好記下權值+端點,畢竟一會兒還要合併它的兩端點呢。

#includeusing namespace std;

#define rep(x,y,z) for(register int x=y; x<=z; x++)

#define downrep(x,y,z) for(register int x=y; x>=z; x--)

#define ll long long

#define ms(x,y,z) memset(x,y,sizeof(z))

#define repedge(x,y) for(register int x=hed[y]; ~x; x=edge[x].nex)

inline int read()

#define mp make_pair

const int n=200005;

const int m=500005;

const ll inf=1e12;

int f[n],pd,n,m;

struct nodee[m];

paire[n];

int gf(int k)

ll boruvka()

const int n=200005;

const int maxlg=30;

const int maxn=n*(maxlg+1);

const ll inf=1e15;

int n,f[n],toc[n],vis[n],ch[maxn][2],id[maxn],cnt;

ll a[n];

paire[n];

vectordt[n];

void trie_init()

int que(int x)

return id[k];

}void ins(int x)

k=ch[k][p];

} id[k]=min(id[k],x);

}ll boruvka()

while(numn) continue;

ll edgenum=(min(x,v)-1)*1ll*n+max(x,v)*1ll-1ll;

e[toc[i]]=min(e[toc[i]],mp((a[v]^a[x])*1ll,edgenum));

}rep(j,0,t-1)

} trie_init();

downrep(i,tmp,1)

rep(j,0,t-1)

} rep(i,1,tmp)

dt[a].clear();

}

} return res;

}int main()

Boruvka 生成樹演算法

boruvka 演算法的一句話思想便是 從所有當前的連通塊向其他連通塊擴充套件出最小邊,直到只剩乙個連通塊 其中取最小邊的貪心思想是 kruskal 的主體,而向外擴充套件又是 prim 的思想 基於另外兩種生成樹演算法,boruvka 的正確性顯然。框架 while 連通塊個數 1 for 每個連...

最小生成樹演算法

由帶權的連通圖生成的數的各邊加起來稱為生成樹的權,把權值最小的生成樹稱為最小生成樹 minimum spanning tree 簡稱為mst 構造最小生成樹的方法就是利用mst性質,一條一條地選擇可以加入的邊。下面介紹兩種用於構造最小生成樹的演算法,其中第一種演算法稱為prim演算法,第二種演算法稱...

最小生成樹演算法

乙個最簡單的最小生成樹 圖結構練習 最小生成樹 time limit 1000ms memory limit 65536k 有n個城市,其中有些城市之間可以修建公路,修建不同的公路費用是不同的。現在我們想知道,最少花多少錢修公路可以將所有的城市連在一起,使在任意一城市出發,可以到達其他任意的城市。輸...