POJ 1258 Agri-Net [最小生成樹] 《挑戰程式設計競賽》2.5
阿新 • • 發佈:2019-02-11
給定各個村子之間的距離, 求最小生成樹
題解:
按題目給的輸入資料來說Prim可能更合適。但我更熟悉Kruskal, 所以強行用Kruskal。
程式碼:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#define MAXN 200
using namespace std;
struct Edge {int from, to, cost;}e[MAXN*MAXN];
int N, M;
int a[MAXN][MAXN];
int f[MAXN];
int ans;
void init() {
for (int i = 1; i <= N; i++) f[i] = i;
}
int find(int x) {
if (f[x] == x) return x;
else return f[x] = find(f[x]);
}
bool same(int x, int y) {
return find(x) == find(y);
}
void unite(int x, int y) {
int fx = find(x);
int fy = find(y);
if (fx != fy) {
f[fx] = fy;
}
}
bool cmp(const Edge &a, const Edge &b) {
return a.cost < b.cost;
}
int kruskal() {
ans = 0;
int k = 0;
for (int i = 0; i < M && k <= N; i++) {
if (!same(e[i].from, e[i].to)) {
ans += e[i].cost;
unite(e[i].from, e[i].to);
k++;
}
}
return ans;
}
int main(){
while (scanf("%d", &N) == 1) {
memset(a, 0, sizeof(a));
M = 0;
for (int i = 1; i <= N; i++)
for (int j = 1; j <= N; j++) {
scanf("%d", &a[i][j]);
if (j > i && a[i][j]) {
e[M].from = i;
e[M].to = j;
e[M].cost = a[i][j];
M++;
}
}
init();
sort(e, e+M, cmp);
ans = kruskal();
printf("%d\n", ans);
}
return 0;
}