/* Name: 最小生成树(kruskal) Author: Try_86 Date: 10/04/12 19:51 */ #include <cstdio> #include <cstdlib> #include <iostream> using namespace std; const int M = 700; int p[27], sum; struct edge { int a; int b; int w; }e[M]; int cmp(const void *a, const void *b) { return (*(edge *)a).w - (*(edge *)b).w; } void init(int vs) { for (int i=1; i<=vs; ++i) p[i] = i; return ; } int find(int v) { if (p[v] != v) p[v] = find(p[v]); return p[v]; } int join(edge e) { int x, y; x = find(e.a); y = find(e.b); if (x != y) { ++sum; p[x] = y; return e.w; } return 0; } int kruskal(int es, int vs) { int ans = 0; init(vs); qsort(e, es, sizeof(edge), cmp); for (int i=0; i<es; ++i) { ans += join(e[i]); if (sum == vs) return ans; } } int main() { int n; while (cin>>n) { if (n == 0) break; char c; int k, w, es; es = 0; for (int i=1; i<n; ++i) { cin>>c>>k; for (int j=0; j<k; ++j) { cin>>c>>w; e[es].w = w; e[es].a = i; e[es].b = c - 'A' + 1; ++es; } } sum = 1; int ans = kruskal(es, n); printf ("%d\n", ans); } return 0; }