題目鏈接: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;
}