poj1258 Agri-Net ——————【 Kruskal 】

来源:互联网 发布:软件实施难吗 编辑:程序博客网 时间:2024/06/11 14:37

这是一道全裸的最小生成树,因为所给的图是对称的且为无向图,所以只需要取一个三角就能把所有边情况表示出来。

#include<stdio.h>#include<limits.h>#include<iostream>#include<string.h>#include<algorithm>using namespace std;const int Max=550;int father[Max];int n,m;struct node{    int st_p;    int en_p;    int co;} edge[Max*Max];void init()         //初始化i的父亲节点为i{    for(int i=0; i<Max; i++)        father[i]=i;}int Find(int x)         //查找x的父亲节点,递归调用{    return father[x]==x? x:father[x]=Find(father[x]);}void Union(int x,int y)       //合并x和y{    x=Find(x),y=Find(y);    if(x!=y)    {        if(x>y)            father[x]=y;        else            father[y]=x;    }}void input(){    m=0;    for(int i=1; i<=n; i++)    {        for(int j=1; j<=n; j++)        {            int temp;            scanf("%d",&temp);            if(i>=j)            //取三角入边                continue;            edge[m].st_p=i;            edge[m].en_p=j;            edge[m++].co=temp;        }    }}bool cmp(node a,node b)     //将边升序排序{    return a.co<b.co;}void kruskal(){    int ans=0,st,en;    sort(edge,edge+m,cmp);    for(int i=0; i<m; i++)    {        st=edge[i].st_p;        en=edge[i].en_p;        st=Find(st);        en=Find(en);        if(st!=en)              //如果不在一个集合中,合并        {            ans+=edge[i].co;            father[en]=st;        }    }    printf("%d\n",ans);}int main(){    while(scanf("%d",&n)!=EOF)    {        init();        input();        kruskal();    }    return 0;}


0 0