题意:
给了n个房子和相应的描述,描述为:两个房子间的距离为x。问该联通网的最短生成树。
关于图的几个概念定义:
- 连通图:在无向图中,若任意两个顶点vivi与vjvj都有路径相通,则称该无向图为连通图。
- 强连通图:在有向图中,若任意两个顶点vivi与vjvj都有路径相通,则称该有向图为强连通图。
- 连通网:在连通图中,若图的边具有一定的意义,每一条边都对应着一个数,称为权;权代表着连接连个顶点的代价,称这种连通图叫做连通网。
- 生成树:一个连通图的生成树是指一个连通子图,它含有图中全部n个顶点,但只有足以构成一棵树的n-1条边。一颗有n个顶点的生成树有且仅有n-1条边,如果生成树中再添加一条边,则必定成环。
- 最小生成树:在连通网的所有生成树中,所有边的代价和最小的生成树,称为最小生成树。
最短生成树详解(转载):
勿在浮沙筑高台
http://blog.csdn.net/luoshixian099/article/details/51908175
模板代码(转载):https://blog.csdn.net/hurmishine/article/details/51244216
AC代码:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int n;
int pre[130];
struct Nedge
{
int start,end;
int cost;
}edge[130];
bool cmp(Nedge a,Nedge b)
{
return a.cost<b.cost;
}
void makeSet()
{
for(int i=0;i<n;i++)
{
pre[i]=i;
}
return ;
}
int find(int x)
{
while(x!=pre[x])
{
x=pre[x];
}
return x;
}
void join(int x,int y)
{
int rootx=find(x);
int rooty=find(y);
if(rootx==rooty)
return;
else
{
pre[rootx]=rooty;
}
return;
}
int kruskal(int n)
{
int sum=0;
makeSet();
for(int i=0;i<n;i++)
{
if(find(edge[i].start)!=find(edge[i].end))
{
join(edge[i].start,edge[i].end);
sum+=edge[i].cost;
}
}
return sum;
}
int main()
{
while(cin>>n)
{
if(n==0) break;
char x,y;
int m,weight;
int counts=0;
for(int i=0;i<n-1;i++)
{
cin>>x>>m;
for(int i=0;i<m;i++)
{
cin>>y>>weight;
edge[counts].start=x-'A';
edge[counts].end=y-'A';
edge[counts].cost=weight;
counts++;
}
}
sort(edge,edge+counts,cmp);
cout<<kruskal(counts)<<endl;
}
}