最小生成树 kruskal算法

一个贪心算法,先排序,然后从小到大开始选边;
同时用并查集来维护两个点是否连通,如果当前边连接的两个点已经连通,那么说明选这条边没有任何意义,一定是劣的(因为前面已经排了序)

#include<bits/stdc++.h>
using namespace std;
const int N = 5005;
const int M = 2e5 + 5;
int n, m, f[N], ans;
struct Edge{
	int u, to, v;
}edge[M];
int find(int x){
	if(f[x] == x) return x;
	return f[x] = find(f[x]);
}
bool cmp(Edge a, Edge b){
	return a.v < b.v;
}
void kruskal(){
	int cnt = 0;
	sort(edge + 1, edge + 1 + m, cmp);
	for(int i = 1; i <= m; i++){
		int fu = find(edge[i].u);
		int ft = find(edge[i].to);
		if(fu == ft) continue;
		ans += edge[i].v;
		f[fu] = ft;
		cnt++;
		if(cnt == n-1) break;
	}
	if(cnt != n-1) ans = 0x3f3f3f3f;
}
int main(){
	cin >> n >> m;
	for(int i = 1; i <= m; i++){
		cin >> edge[i].u >> edge[i].to >> edge[i].v;
	}
	for(int i = 1; i <= n; i++) f[i] = i;
	kruskal();
	if(ans == 0x3f3f3f3f) cout << "orz";
	else cout << ans;
	return 0;
}
posted @ 2025-10-24 21:26  Turkey_VII  阅读(9)  评论(0)    收藏  举报