最小生成樹是什麼?
****自a2392008643的部落格
此演算法可以稱為「加邊法」,初始最小生成樹邊數為0,每迭代一次就選擇一條滿足條件的最小代價邊,加入到最小生成樹的邊集合裡。
把圖中的所有邊按代價從小到大排序;
把圖中的n個頂點看成獨立的n棵樹組成的森林;
按權值從小到**擇邊,所選的邊連線的兩個頂點ui,viui,vi,應屬於兩顆不同的樹,則成為最小生成樹的一條邊,並將這兩顆樹合併作為一顆樹。
重複(3),直到所有頂點都在一顆樹內或者有n-1條邊為止。
**:(題目:loj#123最小生成樹)
#includeusing namespace std;
#define ll long long
ll f[200005],n,m;
void init(ll m)
ll getf(ll x)
bool merge(ll t1,ll t2)
struct nodea[500005];
bool cmp(node a,node b) ,v=v−u=,v=v−u;
在兩個集合u,vu,v能夠組成的邊中,選擇一條代價最小的邊(u0,v0)(u0,v0),加入到最小生成樹中,並把v0v0併入到集合u中。
重複上述步驟,直到最小生成樹有n-1條邊或者n個頂點為止。
**:(不加優化)
#include#define ll long long
using namespace std;
ll n,m,a[5005][5005],vst[5005],dis[5005],ans=0;
void prim(int x)
}vst[k]=1;
ans+=dis[k];
for(j=1;j<=n;j++)
}}int main()
prim(1);
cout**:(鄰接表+堆優化)
#includeusing namespace std;
#define ll long long
priority_queue,vector>,greater> > que;
int head[200010],nxt[1000010],edge[1000010],ver[1000010],tot=0,dis[200010];
bool book[200010];
int n,m,cnt;
ll ans=0;
void add(int x,int y,int z)
int main()
que.push(make_pair(0,1));
while(!que.empty()&&cnt<=n)
printf("%lld",ans);
return 0;
}
不加優化的prim
堆優化的prim
kruskal
時間複雜度
\(\mathcal o(n^2)\)
\(\mathcal o(m\log n)\)
\(\mathcal o(m\log m)\)
適用情況
稠密圖稠密圖
稀疏圖
Prim演算法 Kruskal演算法
一 prim演算法 1 要求 1 生成一顆連通的樹 2 生成樹 包含全部頂點,v 1條邊,沒有迴路,並且新增一條邊會變成有迴路 3 權重和最小 2 過程模擬 最重要 貪心的思想,每一步都要選擇權值最小的,這棵樹所有跟頂點相連的邊中最小的。從根節點開始,讓樹慢慢的長大。過程 從v1開始 跟v1有聯絡的...
Prim演算法 Kruskal演算法
prim演算法 kruskal演算法 prim演算法和kruskal演算法,都是用來找出圖中最小生成樹的演算法,兩個演算法有些小差別。prim演算法 又稱普里姆演算法,以圖上的頂點為出發點,逐次選擇到最小生成樹頂點集距離最短的頂點為最小生成樹的頂點,並加入到該頂點集,直到包含所有的頂點。1.選擇一出...
Prim演算法和Kruskal演算法
一 prim演算法 prim演算法實現的是找出乙個有權重連通圖中的最小生成樹,即 具有最小權重且連線到所有結點的樹。強調的是樹,樹是沒有迴路的 prim演算法是這樣來做的 首先以乙個結點作為最小生成樹的初始結點,然後以迭代的方式找出與最小生成樹中各結點權重最小邊,並加入到最小生成樹中。加入之後如果產...