Kruskal算法
POJ1287
所谓克鲁斯卡尔算法就是先将边按边权从小到大排序,然后贪心选取
在算法运行时应注意避免成环(避圈法)
采用并查集来完成边的合并同时避免成环
#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
#define max 50000
using namespace std;
struct h{
int u;
int v;
int t;
};
bool operator <(const h&a,const h& b){
return a.t<b.t;
}
h a[max];
int f[max];
int cnt;
int n;
int fin(int x){
return x==f[x] ? f[x] : f[x]=fin(f[x]);
}
int Kruskal(){
int ans=0;
int sum=0;
for(int i=0;i<cnt;i++){
if(sum==n-1)
break;
int x=fin(a[i].u);
int y=fin(a[i].v);
if(x!=y){
f[x]=y;
ans+=a[i].t;
sum++;
}
}
return ans;
}
int main(){
int m;
while(cin>>n&&n){
cnt=0;
cin>>m;
if(m==0){
cout<<0<<endl;
continue;
}
for(int i=0;i<m;i++){
int b,c,d;
cin>>b>>c>>d;
a[cnt].u=b;
a[cnt].v=c;
a[cnt].t=d;
cnt++;
a[cnt].u=c;
a[cnt].v=b;
a[cnt].t=d;
cnt++;
}
sort(a,a+cnt);
for(int i=1;i<=n;i++)
f[i]=i;
cout<<Kruskal()<<endl;
}
return 0;
}