题目链接:http://poj.org/problem?id=1251
思路:这道题和poj1258一样,都是赤裸裸的最小成生成树,只是提供数据的方式不一样而已。
///2014.7.7
///poj1251
//Time:16MS
/*
*最小生成树,kruskal算法
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
struct Road
{
int x,y,l;
};
bool cmp(Road a,Road b){
return a.l < b.l;
}
int n;
Road road[500];
int num; //原来路的总数
int sum; //要求的生成树上的路的总长
int dSet[30]; //并查集,用于判断新加入的边是否会与前面的边形成回路
int find(int x){
if( dSet[x] == x )
return x;
else
return find( dSet[x] );
}
int judge(int x,int y){
int fx = find(x);
int fy = find(y);
if( fx==fy )
return false;
else{
dSet[fy] = fx;
return true;
}
}
void init(){
num = 0;
sum = 0;
for(int i=0 ; i<n ; i++)
dSet[i] = i;
char a,b;
int m,temp;
for(int i=0 ; i<n-1 ; i++){
cin>>a>>m;
for(int j=0 ; j<m ; j++){
cin>>b>>temp;
road[num].x = a - 'A';
road[num].y = b - 'A';
road[num].l = temp;
num++;
}
}
}
void kruskal(){
sort(road,road+num,cmp);
int k = 0;
for(int i=0 ; i<n-1 ; ){
if( judge(road[k].x,road[k].y) ){
sum += road[k].l;
i++;
}
k++;
}
}
int main(){
// freopen("in","r",stdin);
// freopen("out","w",stdout);
while( cin>>n && n ){
init();
kruskal();
cout<<sum<<endl;
}
return 0;
}