#include <stdio.h> #include<stdlib.h> struct Edge { int from; int to; int lenght; }; const int max = 27; struct Edge edge[max*max]; int father[max]; int height[max]; int cmp(const void* A, const void* B) { const struct Edge *a = (const struct Edge*) A; const struct Edge *b = (const struct Edge*) B; if (a->lenght > b->lenght) return 1; else if (a->lenght < b->lenght) return -1; else return 0; } void initial(int n) { for (int i = 0; i <= n; i++) { father[i] = i; height[i] = 0; } } void InitialF(struct Edge edge[], int m){ for (int i = 0; i < m; i++){ edge[i].lenght = 101; } } int Find(int x) { if (x != father[x]) { father[x] = Find(father[x]); } return father[x]; } void Union(int a, int b) { a = Find(a); b = Find(b); if (a != b) { if (height[a] < height[b]) { father[a] = b; } else if (height[a] > height[b]) { father[b] = a; } else { father[a] = b; height[a]++; } } } int KrusKal(struct Edge edge[], int m){ //InitialF(edge, m); qsort(edge, m, sizeof(edge[0]), cmp); int cost = 0; for (int i = 0; i < m; i++){ if(Find(edge[i].from) != Find(edge[i].to)){ Union(edge[i].from, edge[i].to); cost+=edge[i].lenght; } } return cost; } int main() { char a, a1; int b, b1; int n; //getchar(); while (scanf("%d", &n) != EOF) { // 注意 while 处理多个 case // 64 位输出请用 printf("%lld") to if (n == 0) break; int m = n*(n-1)/2; int count = 0; for (int j = 0; j < n - 1; j++) { getchar(); scanf("%c %d", &a, &b); if (b == 0) continue; //scanf("%d", &b); //scanf("%c %d", &a, &b); //printf("%d ", a); for (int i = 0; i < b; i++) { getchar(); scanf("%c %d", &a1, &b1); // edge[count].from = a-'A'; edge[count].to = a1-'A'; edge[count++].lenght = b1; //printf("(%d %d)\n", edge[i].from, edge[i].to); } } // for(int i = 0 ; i < count; i++){ // printf("(%d %d %d)", edge[i].from, edge[i].to, edge[i].lenght); // } initial(n); printf("%d\n", KrusKal(edge,count)); } return 0; }