Description
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。
Input
测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( < 100 );随后的 N
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。
Output
对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。
Sample Input
3 3 1 2 1 1 3 2 2 3 4 1 3 2 3 2 0 100
Sample Output
3 ?
1 // Project name : A 2 // File name : main.cpp 3 // Author : Izumu 4 // Date & Time : Tue Jul 10 12:52:14 2012 5 #include<iostream> 6 #include<stdio.h> 7 #include<string.h> 8 #include<algorithm> 9 using namespace std; 10 11 int father[110]; 12 bool flags[110]; 13 14 class country 15 { 16 public: 17 int first, second, value; 18 }; 19 20 country a[5100]; 21 22 23 bool cmp(country x, country y) 24 { 25 return x.value < y.value; 26 } 27 28 int makeset(int n) 29 { 30 for (int i = 1; i <= n; i++) 31 { 32 father[i] = i; 33 } 34 } 35 36 int findset(int x) 37 { 38 if (father[x] != x) 39 { 40 father[x] = findset(father[x]); 41 } 42 return father[x]; 43 } 44 45 int Union(int a, int b) 46 { 47 int x = findset(a); 48 int y = findset(b); 49 if (x == y) 50 { 51 return 1; 52 } 53 else 54 { 55 father[x] = y; 56 return 0; 57 } 58 } 59 60 61 int main() 62 { 63 int n, m; 64 while (cin >> n >> m && n) 65 { 66 int sum = 0; 67 makeset(m); 68 memset(flags, false, sizeof(flags)); 69 for (int i = 1; i <= n; i++) 70 { 71 cin >> a[i].first >> a[i].second >> a[i].value; 72 } 73 sort(a + 1, a + n + 1, cmp); 74 75 for (int i = 1; i <= n; i++) 76 { 77 if (Union(a[i].first, a[i].second) == 0) 78 { 79 sum += a[i].value; 80 } 81 } 82 83 for (int i = 1; i <= m; i++) 84 { 85 flags[findset(i)] = true; 86 } 87 88 int k = 0; 89 for (int i = 1; i <= m; i++) 90 { 91 if (flags[i] == true) 92 { 93 k++; 94 } 95 } 96 97 if (k != 1) 98 { 99 printf("?\n"); 100 } 101 else 102 { 103 printf("%d\n", sum); 104 } 105 106 } 107 108 109 return 0; 110 } 111 // end 112 // ism