1、POJ 1251 Jungle Roads
题意:给出个村庄之间的道路及其维修费;从中选取一些路使道路的维修费最小且保证各村庄之间道路畅通。
思路:最小生成树模板。
①Kruskal
1 #include<iostream> 2 #include<vector> 3 #include<algorithm> 4 using namespace std; 5 int n; 6 struct side 7 { 8 int v1; 9 int v2; 10 int len; 11 side(int vv1=0,int vv2=0,int ll=0):v1(vv1),v2(vv2),len(ll){} 12 friend bool operator <(const side&a,const side&b) 13 { 14 return a.len > b.len; 15 } 16 }; 17 vector<side>minHeap; 18 const int maxn = 30; 19 int pre[maxn]; 20 int Find(int x) 21 { 22 int r = x; 23 while (r != pre[r]) 24 { 25 r = pre[r]; 26 } 27 int c = x, p; 28 while (c != r) 29 { 30 p = pre[c]; 31 pre[c] = r; 32 c = p; 33 } 34 return r; 35 } 36 void Join(int x, int y) 37 { 38 int f1 = Find(x), f2 = Find(y); 39 if (f1 != f2) pre[f1] = f2; 40 } 41 int Kruskal() 42 { 43 side tmp; 44 int cnt = 1; 45 for (int i = 0; i <= n; i++)pre[i] = i; 46 int ans = 0; 47 while (cnt < n) 48 { 49 pop_heap(minHeap.begin(), minHeap.end()); 50 tmp = minHeap.back(); 51 minHeap.pop_back(); 52 int u = Find(tmp.v1); 53 int v = Find(tmp.v2); 54 if (u != v) 55 { 56 Join(tmp.v1, tmp.v2); 57 ans += tmp.len; 58 cnt++; 59 } 60 } 61 return ans; 62 } 63 64 int main() 65 { 66 while (~scanf("%d", &n)) 67 { 68 if (n == 0)break; 69 minHeap.clear(); 70 char v1, v2; 71 int len; 72 int k; 73 for (int i = 0; i < n - 1; i++) 74 { 75 76 cin >> v1; 77 scanf("%d", &k); 78 for (int j = 0; j < k; j++) 79 { 80 cin >> v2; 81 scanf("%d", &len); 82 minHeap.push_back(side(v1 - 'A', v2 - 'A', len)); 83 } 84 } 85 make_heap(minHeap.begin(), minHeap.end()); 86 int ans=Kruskal(); 87 printf("%d\n", ans); 88 } 89 return 0; 90 }