无向图最小生成树

时间:2021-12-03 12:40:25
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 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;
}