题目链接:http://code.hdu.edu.cn/showproblem.php?pid=1879
这条题目我的做法与解决Constructing Roads的解法是相同的。
0 表示没有连通;1代表已连通。在已连通村庄的道路的基础上,找到扩展出来的最小生成树。
1 #include <iostream> 2 #include <algorithm> 3 using namespace std; 4 5 const int maxe = 10000 + 10; 6 int rep[maxe], vis[maxe]; 7 8 struct sets 9 { 10 int v1, v2; 11 int value; 12 } exa[maxe]; 13 14 int cmp(sets a, sets b) 15 { 16 return a.value < b.value; 17 } 18 19 int find(int x) 20 { 21 return x == rep[x] ? x : find(rep[x]); 22 } 23 24 int main() 25 { 26 int i, n, a, b, c, x, y, cnt, flag, sign; 27 while (scanf("%d", &n) != EOF && n) 28 { 29 for (i = 1; i <= n; i++) 30 rep[i] = i; 31 cnt = flag = 0; 32 n *= (n-1)/2; 33 memset(vis, 0, sizeof(vis)); 34 for (i = 0; i < n; i++) 35 { 36 scanf("%d%d%d%d", &a, &b, &c, &sign); 37 if (a > b) 38 swap(a, b); 39 if (sign == 0) 40 { 41 exa[cnt].v1 = a; 42 exa[cnt].v2 = b; 43 exa[cnt].value = c; 44 cnt++; 45 } 46 else 47 { 48 x = find(a); 49 y = find(b); 50 if (x > y) 51 swap(x, y); 52 if (vis[a] && vis[b]) 53 rep[x] = y; 54 else 55 { 56 if (x == y) 57 flag = 1; 58 if (!vis[a] && !vis[b]) 59 { 60 rep[x] = y; 61 vis[a] = vis[b] = 1; 62 } 63 else if (!vis[a]) 64 { 65 rep[x] = y; 66 vis[a] = 1; 67 } 68 else if (!vis[b]) 69 { 70 rep[x] = y; 71 vis[b] = 1; 72 } 73 } 74 } 75 } 76 sort(exa, exa+cnt, cmp); 77 if (!flag) 78 { 79 int minval = 0; 80 for (i = 0; i < cnt; i++) 81 { 82 x = find(exa[i].v1); 83 y = find(exa[i].v2); 84 if (x != y) 85 { 86 minval += exa[i].value; 87 if (x < y) 88 rep[x] = y; 89 else 90 rep[y] = x; 91 } 92 } 93 printf("%d\n", minval); 94 } 95 else 96 printf("0\n"); 97 } 98 return 0; 99 }