kruskal算法求最小生成树
  • 板块学术版
  • 楼主Chengqijun2012
  • 当前回复6
  • 已保存回复7
  • 发布时间2024/8/7 10:08
  • 上次更新2024/8/7 10:22:20
查看原帖
kruskal算法求最小生成树
1202504
Chengqijun2012楼主2024/8/7 10:08
//kruskal算法求最小生成树
//模板
//很好用
//背就完了

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>

using namespace std;

const int N = 5e5 + 100;

int n, m;
int p[N];

struct Edge
{
	int a, b, w;
}edge[N];

bool cmp(Edge a, Edge b)
{
	return a.w < b.w;
}

int find(int x)  //并查集找祖先节点 (懂的都懂)
{
	if(p[x] != x) p[x] = find(p[x]);
	return p[x];
}

int main()
{
	scanf("%d%d\n", &n, &m);
	
	for(int i = 0; i < m; i++)
	{
		int a, b, w;
		scanf("%d%d%d", &a, &b, &w);
		edge[i] = {a, b, w};
	}
	
	sort(edge, edge + m, cmp);
	
	for(int i = 1; i <= n; i++)  //先让每个元素自成一个集合(根节点设为自己)
            p[i] = i;
	
	long long res, cnt; //建议用long long,防止超出int范围
	res = 0;  //总长度
	cnt = 0;  //总边数
	for(int i = 0; i < m; i++)
	{
		int a = edge[i].a, b = edge[i].b, w = edge[i].w;
		a = find(a), b = find(b);
		if(a != b)  //判断a和b的祖先是否不同,如果不同,说明a和b还不连通,执行if里的语句
		{
			p[a] = b;  //把a和b两个节点连起来
			res += w;  //边总长度增加
			cnt++;  //边数加1
		}
	}
 	if(cnt < n - 1)  //判断是否可以造出最小生成树
		puts("impossible");
	else
		printf("%lld\n", res);
	return 0; 
} 
2024/8/7 10:08
加载中...