#include <iostream> #include <cmath> #include <algorithm> using namespace std; const int N=30; int father[N]; int height[N]; struct Edge{ int from,to; int dis; }edge[80]; bool cmp(Edge a,Edge b){ return a.dis<b.dis; } void Initial(){ for(int i=0;i<N;i++){ father[i]=i; height[i]=0; } } int Find(int x){ while(father[x]!=x) x=father[x]; return x; } void Union(int x,int y){ x=Find(x); y=Find(y); if(x!=y){ if(height[x]<height[y]) father[x]=y; else if(height[x]>height[y]) father[y]=x; else{ father[y]=x; height[x]++; } } return; } int kruskal(int n,int edgeNum){ int sum=0; Initial(); sort(edge,edge+edgeNum,cmp); for(int i=0;i<edgeNum;i++){ int x=edge[i].from; int y=edge[i].to; x=Find(x); y=Find(y); if(x!=y){ Union(x,y); sum += edge[i].dis; } } return sum; } int main(){ int n,dis,num,total=0; char chr1,chr2; while(cin>>n){ if(n==0) break; total=0; for(int j=0;j<n-1;j++){ cin>>chr1; cin>>num; for(int i=0;i<num;i++){ cin>>chr2; cin>>dis; edge[total].from=chr1-'A'; edge[total].to=chr2-'A'; edge[total].dis=dis; total++; } } int answer = kruskal(n,total); //总结点数,总边数 cout<<answer<<endl; } return 0; }