#include<iostream>//PRIM版
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
int forest[30][30];
int dis[30];
bool vis[30];
int num;
void prim() {
int result = 0;
for (int i = 0; i < num; i++) {
dis[i] = forest[0][i];
}
vis[0] = true;
for (int i = 0; i < num - 1; i++) {//num-1条边
int _min;//index
int min = inf;
for (int j = 0; j < num; j++) {
if (min > dis[j] && !vis[j]) {
min = dis[j];
_min = j;
}
}
vis[_min] = true;
result += min;
//printf("v--%c cost:%d\n", _min + 'A', min);
for (int i = 0; i < num; i++) {
if (!vis[i] && dis[i] > forest[_min][i]) {
dis[i] = forest[_min][i];
}
}
}
cout << result << endl;
}
int main() {
int n;
while (cin >> n) {
num = n;
if (!n)
break;
memset(forest, inf, sizeof(forest));
for (int i = 0; i < num; i++) {
forest[i][i] = 0;
}
memset(vis, false, sizeof(vis));
while (--n) {
char head;
cin >> head;
int temp = head - 'A';
int num;
cin >> num;
while (num--) {
char tail;
cin >> tail;
cin >> forest[temp][tail - 'A'];
forest[tail - 'A'][temp] = forest[temp][tail - 'A'];
}
}
//for (int i = 0; i < num; i++) {
// for (int j = 0; j < num; j++) {
// printf("%c->%c:%d\n", i + 'A', j + 'A', forest[i][j]);
// }
//}
prim();
}
return 0;
}
#include<iostream>//Kruskal版
#include<algorithm>
#include<cstring>
using namespace std;
int tree[30];
struct Edge {
int head;
int tail;
int cost;
bool operator <(const Edge&A)const{
return cost < A.cost;
}
}edges[80];
int findroot(int a) {
if (tree[a] == -1)//找到根节点
return a;
int temp = findroot(tree[a]);
tree[a] = temp;//路径压缩
return temp;
}
int main() {
int n;
while (cin >> n) {
if (!n)
break;
int size = 0;
memset(tree, -1, sizeof(tree));
while (--n) {
char head;
cin >> head;
int temp=head - 'A';
int num;
cin >> num;
while (num--) {
char tail;
cin >> tail;
edges[size].head = temp;
edges[size].tail = tail - 'A';
cin>>edges[size].cost;
size++;
}
}
//for (int i = 0; i < size; i++) {
//
// printf("%c->%c cost:%d\n", edges[i].head + 'A', edges[i].tail + 'A', edges[i].cost);
//}
//cout << "*************" << endl;
sort(edges, edges + size);
//for (int i = 0; i < size; i++) {
// printf("%c->%c cost:%d\n", edges[i].head + 'A', edges[i].tail + 'A', edges[i].cost);
//}
int result = 0;
for (int i = 0; i < size; i++) {
int heads_root = findroot(edges[i].head);
int tails_root = findroot(edges[i].tail);
if (heads_root != tails_root) {
tree[tails_root] = heads_root;
result += edges[i].cost;
//printf("%c->%c cost:%d\n", edges[i].head + 'A', edges[i].tail + 'A',edges[i].cost);
}
}
cout << result << endl;
}
return 0;
}