首页 > 代码库 > 最小生成树Kruskal算法

最小生成树Kruskal算法

Kruskal算法就是把图中的所有边权值排序,然后从最小的边权值开始查找,连接图中的点,当该边的权值较小,但是连接在途中后会形成回路时就舍弃该边,寻找下一边,以此类推,假设有n个点,则只需要查找n-1条边即可。

#include<stdio.h>#include<iostream>#include<algorithm>#include<string.h>using namespace std;const int maxn=1000;int v,l;///v代表点的个数,l代表边的个数int fa[maxn],son[maxn];struct Kruskal{///该结构体时存储点与这两点之间的距离的int a,b;int value;}edge[maxn];bool cmp(Kruskal x,Kruskal y){///把边的权值按从小到大的顺序排列return x.value<y.value;}int fin(int x)///寻找x的根结点{    return fa[x]==x?fa[x]:fin(fa[x]);}bool unin(int x,int y){    int root1,root2;    root1=fin(x);    root2=fin(y);    if(root1==root2){        return false;///当输入的两个点有相同的根结点时成环,返回false    }    else if(son[root1]>=son[root2]){        fa[root2]=root1;///root2的根结点时root1        son[root1]+=son[root2];///把数量少的那棵树连接到数量多的那棵树    }    else {        fa[root1]=root2;        son[root2]+=son[root1];    }    return true;///只要两个点不在同一个根结点上就返回true}int main(){    int n,total,sum,flag;    cin>>n;    while(n--){        cin>>v>>l;        total=0;        sum=0;        flag=0;        for(int i=1;i<=v;i++){///初始化            fa[i]=i;            son[i]=1;        }        for(int i=1;i<=l;i++){            cin>>edge[i].a>>edge[i].b>>edge[i].value;        }        sort(edge+1,edge+1+l,cmp);///因为edge时从1开始的,所以edge要+1        for(int i=1;i<=l;i++){            if(unin(edge[i].a,edge[i].b)){                total++;                sum+=edge[i].value;///记录最小的权值                cout<<edge[i].a<<"->"<<edge[i].b<<endl;            }            if(total==v-1){///有n个结点就有n-1条边构成最小生成树                flag=1;                break;            }        }        if(flag)cout<<sum<<endl;        else cout<<"data error ."<<endl;    }        }

 

最小生成树Kruskal算法