最小生成樹(mst),無向圖,什麼是最小生成樹,最小生成樹就是包括所有頂點(不一定成環)且權值之和最小,涉及到這類題目,有時候題目保證一定有最小生成樹,沒有題目會說沒有輸出-1等等,怎麼判斷有沒有下面講解過程中提到,與最小生成樹相反的是最大生成樹,有時候題目保證一定有最大生成樹,沒有題目會說沒有輸出-1等等,怎麼判斷有沒有下面講解過程中提到。
最小生成樹的演算法有兩個乙個是prim演算法另乙個是kruskal演算法
prim演算法
演算法描述:任意選出乙個頂點作為初始頂點(我都是選第乙個頂點),v是頂點的集合,一開始為空,以後陸續將頂點加入集合,全部頂點加入集合就得到最小生成樹,
任選乙個頂點放入樹,初始化v和lowcost
在那些乙個頂點在樹里另乙個端點不在樹里的邊中選乙個邊權最小的邊,將此邊和端點加入數,執行更新,重複上一步知道所有頂點都入樹
實現**:
void prim()
memset(v,0,sizeof(v));
v[1]=1;
for(i=1;i<=n;i++)n節點個數
lowcost[i]=edge[1][i];
for(i=2;i<=n;i++)n節點個數
min=inf;(最大生成樹時min=-inf)
for(j=1;j<=n;j++)
if(!v[j]&&minn>lowcost[j])(求最大生成樹時if(!v[j]&&minnminn=lowcost[j];
next=j;
判斷是否能構成最小生成樹
if(minn==inf)
if(k=頂點個數-1) 樹已生成
實現**:
struct node
int s,e,v;//起點終點權值
bool cmp(node a,node b)
return a.vint find(int x)
if(fat[x]!=x)
fat[x]=find(fat[x]);
return fat[x];
void nuionn(int x,int y)
int fa=find(x);
int fb=find(y);
if(fa!=fb) fat[fa]=fb;
int main()
如果以矩陣的形式給出
m=0;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
cin>>x;
if(x!=0)
m++;
edge[m].s=i;
edge[m].e=j;
edge[m].v=x;
如果不以矩陣的形式給出
for(i=1;i<=m;i++)//m邊數
cin>>a>>b>>c;
edge[i].s=a;edge[i].e=b;edge[i].v=c;
for(i=1;i<=n;i++) fat[i]=i;n是頂點的個數
sort(edge+1,edge+1+m,cmp);
tot=0;k=0;
for(i=1;i<=m;i++)m邊數
if(find(edge[i].s)!=find(edge[i].e)
union(edge[i].s,edge[i].e);
tot+=edge[i].v;
k++;
if(k==n-1) cout 最小生成樹講解 從點的方面考慮構建一顆 mst,大致思想 設圖 g頂點集合為 u,首先任意選擇圖 g中的一點作為起始點 a,將該點加入集合 v,再從集合 u v中找到另一點 b使得點b到 v中任意一點 的權值最小,此時將 b點也加入集合 v 以此類推,現在的集合 v 再從集合 u v中找到另一點 c... 最小生成樹的方法一般比較常用的就是kruskal和prim演算法 乙個是按邊從小到大加,乙個是按點從小到大加,兩個方法都是比較常用的,都不是很難。kruskal演算法在本文裡我就不講了,本文的重點是講講prim演算法,之前一直沒學過,只是了解了思想,原本以為很難,結果很好理解 prim 即可以用過鄰... 普里姆演算法 稠密圖 克魯斯卡爾演算法 稀疏圖 1.prime 演算法 貪心 集合加點 2.kruskal演算法 並查集 加邊 思想是加 點,在邊比較多的情況下,用prime。思路 先找 任意一點到其他的點的 最短距離,再找 這個點和剛才的點 到其他的點的最短距離,依次重複 最小生成樹 prime模...最小生成樹 講解
講解 prim演算法《最小生成樹》
2013寒假ACM集訓 最小生成樹