题目71:还是畅通工程

来源:互联网 发布:七天网络阅卷成绩查询 编辑:程序博客网 时间:2024/05/18 00:28

浙大计算机研究生复试上机考试-2006年

http://acm.hdu.edu.cn/showproblem.php?pid=1233

http://ac.jobdu.com/problem.php?cid=1040&pid=70

使用克鲁斯卡尔_并查集  求最小生成树

#include <stdio.h>#include <algorithm>           //使用sort(start,end,cmp)函数using namespace std;           //必须在std下  
int Tree[100];int findRoot(int x){if (Tree[x]==-1){return x;}else{int tmp=findRoot(Tree[x]);Tree[x]=tmp;return tmp;}}struct Edge         //边结构体{int a,b;       //边两个顶点编号int cost;      //权值}edge[5000];                    //n*(n-1)/2条边  n<100bool cmp(Edge a,Edge b)        //等效于重载<{return a.cost<b.cost;}int main(){int n,i;while (scanf("%d",&n)!=EOF && n!=0){for (i=1;i<=n*(n-1)/2;i++)      //输入{           scanf("%d%d%d",&edge[i].a,&edge[i].b,&edge[i].cost);}sort(edge+1,edge+1+n*(n-1)/2,cmp); //注意首尾,从1 ~ n*(n-1)/2,权值递增排列for (i=1;i<=n;i++)               //初始所有节点孤立{Tree[i]=-1;}int ans=0;               //最小生成树上初始权值和为0for (i=1;i<=n*(n-1)/2;i++)   //从小到大遍历所有边,两个端点不在一个集合则合并(选取该边){int a=findRoot(edge[i].a);     //当前最小边的两个顶点信息int b=findRoot(edge[i].b);if (a!=b)                    //当前两个节点不在一个集合,合并这两个集合{Tree[a]=b;              ans+=edge[i].cost;}                           }printf("%d\n",ans);}return 0;}//克鲁斯卡尔定理:先将所有边从小到大排序//                依次选择最小边,若边的两个顶点在不同集合,则合并//                若最终只剩一个集合且包含所有顶点,则原图是连通图,得到最小生成树,否则原图不连通


 

原创粉丝点击