基本最小生成树—Kruskal

来源:互联网 发布:qq输入法 linux 编辑:程序博客网 时间:2024/05/24 05:50
/*对权值进行排序,然后从小到大进行判断,如果加入这条边,不成环则是所求树的边。 (并查集) */#include <iostream>#include <algorithm>#include <cstdio>using namespace std;int par[1020];int ran[1020];struct edge{    int u,v,dis;}e[1020];bool cmp(edge a,edge b)// 以边由小到大排序 {    return a.dis<b.dis;}int find(int x)  //查找根节点 {    int r = x;    while(par[r]!=r)    {        r = par[r];    }    int i = x,j;    while(par[i]!=r)    {        j = par[i];        par[i] = r;        i = j;    }    return r;}void merge(int x,int y)  {    x = find(x);    y = find(y);    if(ran[x]<ran[y])    par[x] = y;    else    {        par[y] = x;        if(ran[x]==ran[y])        ran[x]++;    }}int main(){    int n;    while(scanf("%d",&n),n)    {        int m;        cin>>m;        for(int i = 1;i<=n;i++)        {            par[i] = i;            ran[i] = 0;        }        for(int i = 0;i<m;i++)        {            cin>>e[i].u>>e[i].v>>e[i].dis;        }        sort(e,e+m,cmp);        int sum = 0;        for(int i = 0;i<m;i++)        {            if(find(e[i].u)!=find(e[i].v)) // 如果两点根节点不同,将他们合并并且加入生成图中             {                sum+=e[i].dis;                merge(e[i].u,e[i].v);            }        }        cout<<sum<<endl;    }    return 0;}/*6 101 2 61 4 54 6 2 6 5 65 2 31 3 13 4 53 6 43 5 63 2 515*/