最小生成树Kruskal算法和POJ1287样例
先把所有的边和其边权存下来,在按照边权进行排序。其次便是利用并查集的基本算法进行操作。
这里你可以注意一下,和并查集不同的是这里要判断你现在操作的边对应的两个点是否已经在fat[maxn]中了,
如果是的话这条边舍弃,不保存其边权。
建议先看看并查集算法在来理解这个算法,可以说这个算法只是在并查集上面进行小改动的。
https://blog.csdn.net/hai200103/article/details/107590515
模板为这几个函数加上int main()中的判断m条边的处理。
函数详情可以看并查集的链接,有作用详解。
#include<iostream>
#include<algorithm>
#include<cstring>
#define maxn 55*55/2
using namespace std;
struct node{
int form,to,dis;
}edge[maxn];
int fat[maxn],m;
bool cmp(node a,node b){
return a.dis<b.dis;
}
int father(int x){
if(fat[x]!=x)
return fat[x]=father(fat[x]);
return x;
}
void unionn(int x,int y){
fat[father(y)]=father(x);
}
void init(){
for(int i=1;i<=m;i++)
fat[i]=i;
}
int main()
{
int i,j,k,totle,n;
while(cin>>n){
if(n==0)break;
cin>>m;
totle=0,k=0;
for(i=1;i<=m;i++)
{
cin>>edge[i].form>>edge[i].to>>edge[i].dis;
}
init();
sort(edge+1,edge+1+m,cmp);
for(i=1;i<=m;i++)//对m条边进行处理
{
if(k==n-1)break;//找到了n-1条边,离开
if(father(edge[i].form)!=father(edge[i].to))//找出不在最小生成树中的边
{
unionn(edge[i].form,edge[i].to);
k++;
totle+=edge[i].dis; //边权相加
}
}
cout<<totle<<endl;
}
return 0;
}