poj 1251 Jungle Roads

#include <iostream>        // 最小生成树kruskal算法
#include <algorithm>
using namespace std;
const int maxn=30,maxm=80;
int n,m; //n,m分别是结点数和边数
int p[maxn]; //记录并查集中该结点的父亲
int u[maxm],v[maxm],w[maxm]; //保存边的端点序号和权值
int r[maxm]; //用于间接排序--排序的关键字是对象的“代号”,而不是对象本身
int cmp(const int i,const int j)
{
return w[i]<w[j];
}
int find(int x)
{
return p[x]==x ? x : p[x]=find(p[x]);
}
int Kruskal()
{
int i,e,x,y;
for(i=0;i<n;++i) //n个结点
p[i]=i;
for(i=0;i<m;++i) //m条边
r[i]=i;
sort(r,r+m,cmp); //按权重对m条边从小到大排序
int sum=0,cnt=0; //sum记录最小生成树的权值
for(i=0;i<m;++i)
{
e=r[i]; //边的下标
x=find(u[e]);
y=find(v[e]);
if(x!=y) //在不同的连通分量
{
sum+=w[e];
p[x]=y;
cnt++;
if(cnt==n-1) //n个结点的最小生成树有n-1条边
break;
}
}
return sum;
}
int main()
{
while(cin>>n&&n) //结点下标从0开始
{
m=0;
char ch;
int num,wei;
for(int i=0;i<n-1;++i)
{
cin>>ch>>num;
while(num--)
{
cin>>ch>>wei;
u[m]=i;
v[m]=ch-'A';
w[m]=wei;
m++;
}
}
printf("%d\n",Kruskal());
}
return 0;
}

posted on 2011-07-22 19:04  sysu_mjc  阅读(113)  评论(0编辑  收藏  举报

导航