POJ 1258 - Agri-Net
http://poj.org/problem?id=1258
概要
N 個の農場を光ファイバーで繋ぐ. ある農場と別の農場を繋ぐのに必要なコストが与えられる.
どの農場から別のどの農場への経路が存在するように繋いだとき,それに必要な最小のコストを答える.
制約
- 3 <= N <= 100
解法
最小全域木.なぜか priority_queue を使ってた.
poj/1258.cc1 #include <iostream> 2 #include <vector> 3 #include <queue> 4 using namespace std; 5 6 class DisjointSet { 7 private: 8 vector<int> parent; 9 10 int root(int x) 11 { 12 if (parent[x] < 0) { 13 return x; 14 } else { 15 parent[x] = root(parent[x]); 16 return parent[x]; 17 } 18 } 19 20 public: 21 DisjointSet(int size) : parent(size, -1) {} 22 23 bool unite(int x, int y) 24 { 25 const int a = root(x); 26 const int b = root(y); 27 if (a != b) { 28 if (parent[a] < parent[b]) { 29 parent[a] += parent[b]; 30 parent[b] = a; 31 } else { 32 parent[b] += parent[a]; 33 parent[a] = b; 34 } 35 return true; 36 } else { 37 return false; 38 } 39 } 40 41 bool find(int x, int y) 42 { 43 return root(x) == root(y); 44 } 45 46 int size(int x) 47 { 48 return -parent[root(x)]; 49 } 50 }; 51 52 struct Edge { 53 int from, to, weight; 54 Edge(int f, int t, int w) : from(f), to(t), weight(w) {} 55 56 bool operator<(const Edge& e) const 57 { 58 return weight > e.weight; 59 } 60 }; 61 62 int kruskal(priority_queue<Edge> edges, const int N) 63 { 64 DisjointSet s(N); 65 int ttl = 0; 66 while (s.size(0) < N) { 67 const Edge e = edges.top(); 68 edges.pop(); 69 if (s.unite(e.from, e.to)) { 70 ttl += e.weight; 71 } 72 } 73 return ttl; 74 } 75 76 int main(void) 77 { 78 int N; 79 while (cin >> N) { 80 priority_queue<Edge> edges; 81 for (int i = 0; i < N; i++) { 82 for (int j = 0; j < N; j++) { 83 int w; 84 cin >> w; 85 edges.push(Edge(i, j, w)); 86 } 87 } 88 cout << kruskal(edges, N) << endl; 89 } 90 }