洛谷P1546 最短网络 Agri-Net(最小生成树,Kruskal)

时间:2021-07-20 06:12:09

洛谷P1546 最短网络 Agri-Net

最小生成树模板题。

直接使用 Kruskal 求解。

复杂度为 \(O(E\log E)\) 。

#include<stdio.h>
#include<string.h>
#include<algorithm> using namespace std; const int maxn = 105 * 105;
int n, x, tot, ans, f[105];
struct edge{
int from, to, w;
bool operator < (const edge & _edge) const {
return w < _edge.w;
}
}e[maxn]; void init(){
for(int i = 1; i <= n; i++) f[i] = i;
}
int father(int x){
if(f[x] != x){
f[x] = father(f[x]);
}
return f[x];
}
void _union(int a, int b){
int fa = father(a), fb = father(b);
f[fa] = f[fb];
}
int ok(int a, int b){
int fa = father(a), fb = father(b);
return fa == fb ? 1 : 0;
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
scanf("%d", &x);
if(i < j){
tot++;
e[tot].from = i; e[tot].to = j; e[tot].w = x;
}
}
}
init();
int m = n * (n - 1) / 2;
int cnt = 0;
sort(e + 1, e + 1 + m);
for(int i = 1; i <= m; i++){
if(!ok(e[i].from, e[i].to)){
ans += e[i].w;
_union(e[i].from, e[i].to);
cnt++;
if(cnt == n - 1) break;
}
}
printf("%d\n", ans);
return 0;
}