1.用kruskal算法。
2.用并查集连接两点,防止环路。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
struct Edge
{
char start;
char last;
int cost;
} roads[80];
int father[200];
int roads_num;
int cmp(const void* a, const void* b)
{
return ((Edge*)a)->cost - ((Edge*)b)->cost;// 升序
}
int find_father(int x)
{
if(father[x]!=x)
{
father[x]=find_father(father[x]);
}
//printf("father[%d]=%d ",x,father[x]);
//else
return father[x];//--->不能用else。
}
int union_roads(int u,int v)
{
u=find_father(u);
v=find_father(v);
if(u!=v)//--->防止成环
{
//printf("OK!\n");
father[v]=u;
//printf("fatherv[%d]=%d ",v,father[v]);
return 1;
}
else
return 0;
//return 0;
}
int kruskal()
{
int u,v;
int min_cost=0;
for(int i=0;i<=roads_num;i++)
{
u=roads[i].start;
v=roads[i].last;
//cout<<roads[i].cost<<endl;
if(union_roads(u,v))
{
min_cost+=roads[i].cost;
}
}/*
for(int i='A';i<='Z'+20;i++)
{
//cout<<"f["<<i<<"]"<<father[i]<<endl;
}*/
return min_cost;
}
int main()
{
int n,num,cost;
char start,last;
while(cin>>n&&n)
{
roads_num=-1;
for(int f='A';f<='Z';f++)
{
father[f]=f;
//printf("father[%d]=%d\n",f,father[f]);
}
for(int i=1; i<n; i++)
{
cin>>start>>num;
//cout<<"----"<<start<<num<<endl;
for(int j=0; j<num; j++)
{
cin>>last>>cost;
//cout<<"_____"<<last<<cost<<endl;
roads[++roads_num].start=start;
roads[roads_num].last=last;
roads[roads_num].cost=cost;
}
}
qsort(roads,roads_num+1,sizeof(struct Edge),cmp);
/*
for(int j=0;j<=roads_num;j++)
{
cout<<roads[j].start<<"->"<<roads[j].last<<" "<<roads[j].cost<<endl;
}*/
printf("%d\n",kruskal());
}
return 0;
}