1 View Code
2
3 #include<iostream>
4 #include<algorithm>
5 using namespace std;
6
7 const int size = 128;
8 int n;
9 int father[size];
10 int rank[size];
11
12 //把每条边成为一个结构体,包括起点、终点和权值
13 typedef struct node
14 {
15 int val;
16 int start;
17 int end;
18 }edge[SIZE * SIZE / 2];
19
20 //把每个元素初始化为一个集合
21 void make_set()
22 {
23 for(int i = 0; i < n; i ++){
24 father[i] = i;
25 rank[i] = 1;
26 }
27 return ;
28 }
29
30 //查找一个元素所在的集合,即找到祖先
31 int find_set(int x)
32 {
33 if(x != father[x]){
34 father[x] = find_set(father[x]);
35 }
36 return father[x];
37 }
38
39 //合并x,y所在的两个集合:利用Find_Set找到其中两个
40 //集合的祖先,将一个集合的祖先指向另一个集合的祖先。
41 void Union(int x, int y)
42 {
43 x = find_set(x);
44 y = find_set(y);
45 if(x == y){
46 return ;
47 }
48 if(rank[x] < rank[y]){
49 father[x] = find_set(y);
50 }
51 else{
52 if(rank[x] == rank[y]){
53 rank[x] ++;
54 }
55 father[y] = find_set(x);
56 }
57 return ;
58 }
59
60 bool cmp(pnode a, pnode b)
61 {
62 return a.val < b.val;
63 }
64
65 int kruskal(int n) //n为边的数量
66 {
67 int sum = 0;
68 make_set();
69 for(int i = 0; i < n; i ++){ //从权最小的边开始加进图中
70 if(find_set(edge[i].start) != find_set(edge[i].end)){
71 Union(edge[i].start, edge[i].end);
72 sum += edge[i].val;
73 }
74 }
75 return sum;
76 }
77
78 int main()
79 {
80 while(1){
81 scanf("%d", &n);
82 if(n == 0){
83 break;
84 }
85 char x, y;
86 int m, weight;
87 int cnt = 0;
88 for(int i = 0; i < n - 1; i ++){
89 cin >> x >> m;
90 //scanf("%c %d", &x, &m);
91 //printf("%c %d ", x, m);
92 for(int j = 0; j < m; j ++){
93 cin >> y >> weight;
94 //scanf("%c %d", &y, &weight);
95 //printf("%c %d ", y, weight);
96 edge[cnt].start = x - 'A';
97 edge[cnt].end = y - 'A';
98 edge[cnt].val = weight;
99 cnt ++;
100 }
101 }
102
103 sort(edge, edge + cnt, cmp); //对边按权从小到大排序
104 cout << kruskal(cnt) << endl;
105 }
106 }