最小生成树 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;
}

浙公网安备 33010602011771号