1. 程式人生 > >POJ 1258 Agri-Net [最小生成樹] 《挑戰程式設計競賽》2.5

POJ 1258 Agri-Net [最小生成樹] 《挑戰程式設計競賽》2.5

給定各個村子之間的距離, 求最小生成樹

題解:

按題目給的輸入資料來說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; }