C++ P3366 【模板】最小生成樹
阿新 • • 發佈:2018-11-11
不談
直接上程式碼。
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; struct Edge{ int u,v; int w; }; Edge edgeArray[200000+5]; int pointFatherArray[5000+5]; int compareTo(Edge a,Edge b){ return a.w<b.w; } int find(int x){ return x==pointFatherArray[x]?x:pointFatherArray[x]=find(pointFatherArray[x]); } int kruskal(int pointAmount,int edgeAmount){ int totalWeight=0; int totalEdgeAmount=0;//最小生成樹的邊數 for(int i=0;i<edgeAmount;i++){ Edge edge=edgeArray[i]; int uPointFather=find(edge.u); int vPointFather=find(edge.v); if(uPointFather==vPointFather)continue; totalWeight+=edge.w;//注意 不要忘記加總權重啊 pointFatherArray[uPointFather]=vPointFather; totalEdgeAmount++; if(totalEdgeAmount==pointAmount-1){ return totalWeight; } } return totalWeight; } int main(){ int pointAmount,edgeAmount; scanf("%d%d",&pointAmount,&edgeAmount); for(int i=0;i<edgeAmount;i++){ //Edge edge=edgeArray[i]; //cin>>edge.u>>edge.v>>edge.w; 注意 不要這樣寫!! cin>>edgeArray[i].u>>edgeArray[i].v>>edgeArray[i].w; } for(int i=1;i<=pointAmount;i++){//不要忘記預處理pointFatherArray pointFatherArray[i]=i; } sort(edgeArray,edgeArray+edgeAmount,compareTo); int totalWeight=kruskal(pointAmount,edgeAmount); cout<<totalWeight<<endl; return 0; }
怎麼學呢?首先,看紫書,大概看懂之後,你可能是懵逼的。(像我一樣)
接下來我們看一下程式碼。
…程式碼大概挺好懂的QAQ我就不解釋了(其實是不知道咋解釋)
由於這道題的特殊性(只需要求出總權值即可),所以我們直接扔了並查集壓縮路徑(就是讓子結點的父結點直接設定為最大的父結點,這樣訪問子結點的最大的父結點就快了),也就是說我們結束之後沒法輸出最小生成樹的樣子。
某蒟蒻:那麼我該怎麼輸出最小生成樹的樣子呢QAQ
zyc大佬:記錄每一次留下的邊