#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
template<class T> bool up_max(T& a,const T& b) {return b>a? a=b,1:0;}
template<class T> bool up_min(T& a,const T& b) {return b<a? a=b,1:0;}
const int maxn = 27;
const int inf = 1000000000;
int g[maxn][maxn];
int dis[maxn];
int vis[maxn];
int n;
int prime()
{
int mincost = 0;
for(int i = 1; i <= n; i++)
vis[i] = 0;
for(int i = 2; i <= n; i++)
{
dis[i] = g[1][i];
}
vis[1] = 1;dis[1]= 0;
for(int i = 1; i < n; i++)
{
int mindis = inf, idx = -1;
for(int j = 1; j <= n; j++)
if(!vis[j]&&up_min(mindis, dis[j]))
idx = j;
vis[idx] = 1;
mincost += mindis;
for(int i = 1; i <= n; i++)
{
if(!vis[i])
up_min(dis[i], g[idx][i]);
}
}
return mincost;
}
int main()
{
while(scanf("%d\n", &n)!=EOF)
{
if(n==0)break;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
g[i][j] = inf;
for(int i = 1; i < n; i++)
{
char ch;
int m;
scanf("%c%d\n", &ch, &m);
while(m--)
{
char ch1;
int d;
scanf("%c%d", &ch1, &d);
if(d==0)break;
g[ch-'A'+1][ch1-'A'+1] = d;
g[ch1-'A'+1][ch-'A'+1] = d;
getchar();
}
}
int mincost = prime();
printf("%d\n", mincost);
}
}
用查并集的方法,,借鉴别人的;;
#include<stdio.h>
#include<string.h>
int root[30];
int find(int x)
{
int r=x;
while(root[r]!=r)
r=root[r];
return r;
}
void merge(int x,int y)
{
if(find(x)!=find(y))
{
if(find(x)<find(y))
root[find(y)]=find(x);
else
root[find(x)]=find(y);
}
}
int main()
{
int n,i,j,k,x,y,min,sum,cost[30][30];
char ch1,ch2;
while(scanf("%d",&n),n)
{
getchar();
memset(cost,-1,sizeof(cost));//开始默认为负
for(i=1; i<n; i++)
{
root[i]=i;//root数组初始化
scanf("%c %d",&ch1,&k);
for(j=1; j<=k; j++)
{
scanf(" %c %d",&ch2,&x);
cost[i][ch2-'A'+1]=x;//把输入的字母与相应的数字对应起来,A:1,B:2,...
}
getchar();//防止回车被读入
}
root[n]=n;//
sum=0;
for(k=1; k<n; k++) //控制次数
{
min=100000;
for(i=1; i<n; i++) //筛选最小值
{
for(j=i+1; j<=n; j++)
{
if(find(i)!=find(j) && cost[i][j]>0 && cost[i][j]<min)
{
min=cost[i][j];
x=i;
y=j;
}
}
}
sum+=min;
merge(x,y);
}
printf("%d\n",sum);
}
return 0;
}