题目大意:给出村庄的道路连接情况以及维护需要的花费,求连通每个村庄最小花费的道路。
解题思路:很裸的最小生成树的题目,直接利用Kruskal算法求解最小生成树即可,详见code。
题目来源:http://poj.org/problem?id=1251
http://acm.hdu.edu.cn/showproblem.php?pid=1301
code:
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 100+10;
int p[30];
int n,m,val,num;
char str,arr;
struct edge{
int u,v,w;
}e[MAXN*MAXN];
int cmp(const edge a,const edge b){return a.w<b.w;} //间接排序函数
int find(int x){return p[x]==x?x:p[x]=find(p[x]);} //并查集的find函数
int Kruskal(){
int ans=0;
for(int i=1;i<=30;i++) p[i]=i; //初始化并查集
sort(e+1,e+1+m,cmp); //对边排序,按照权值
for(int i=1;i<=m;i++){ //遍历当前的两点,是否在同一个集合
int x=find(e[i].u);
int y=find(e[i].v);
if(x!=y){ //如果不在同一个集合进行合并
ans+=e[i].w;
p[x]=y;
}
}
return ans;
}
int main(){
while(scanf("%d",&n)!=EOF && n){
m=0;
for(int i=0;i<n-1;i++){
scanf("%s%d",&str,&num);
if(num==0) continue;
for(int j=0;j<num;j++){
scanf("%s%d",&arr,&val);
++m; //边集下标
e[m].u=str-'A'+1;
e[m].v=arr-'A'+1;
e[m].w=val;
}
}
printf("%d\n",Kruskal());
}
return 0;
}