无向图最小生成树

来源:互联网 发布:js定义数组赋值 编辑:程序博客网 时间:2024/05/23 21:22
1212 无向图最小生成树


N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树。
Input
第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量。(2 <= N <= 1000, 1 <= M <= 50000)第2 - M + 1行:每行3个数S E W,分别表示M条边的2个顶点及权值。(1 <= S, E <= N,1 <= W <= 10000)
Output
输出最小生成树的所有边的权值之和。
Input示例
9 141 2 42 3 83 4 74 5 95 6 106 7 27 8 18 9 72 8 113 9 27 9 63 6 44 6 141 8 8
Output示例
37
#include <stdio.h>#include <algorithm>using namespace std;int c[1001];struct  EDGE{int a,b,w;              //创建一个用来表示边的结构体,其中a和b分别代表边的两个顶点,w则代表这条边的权值; }edge[50001];bool cmp(EDGE a,EDGE b){return a.w<b.w;        //排序函数,用来将无向图的各条边按照权值从小到大的顺序排列; }int find(int x){if(c[x]==x)   return x;return c[x]=find(c[x]);          //find函数用来寻找未构成的某子图的根节点; }int main(){int n,m;while(~scanf("%d%d",&n,&m))     //输入点的个数和边的个数; {for(int i=1; i<=m; i++){scanf("%d%d%d",&edge[i].a,&edge[i].b,&edge[i].w);   //分别输入各条边的顶点和这条边的权值; }for(int j=1; j<=n; j++){c[j]=j;                            //对于开始时未构图时我们将每个点的根节点定义为它本身; }sort(edge+1,edge+m+1,cmp);          //对各条边进行权值排序; int ans=0;    for(int j=1; j<=m; j++)    {    int a=find(edge[j].a);         //从1开始遍历每一条边,找出这条边的两个顶点的根节点;     int b=find(edge[j].b);    if(a!=b)    {    c[a]=b;                  //如果这两个点的母节点不同的话,则将其中一个顶点根节点的根节点设置为另一个顶点的根节点;     ans+=edge[j].w;          //用ans来计录这个最小生成树各条边的权值之和; }}printf("%d\n",ans);}return 0;}