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 14 1 2 4 2 3 8 3 4 7 4 5 9 5 6 10 6 7 2 7 8 1 8 9 7 2 8 11 3 9 2 7 9 6 3 6 4 4 6 14 1 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; }