kruskal
算法步骤:
1
、
1、
1、将所有的边按照边权由小到大排序
2
、
2、
2、当一条边的两个顶点不相通,则加进去,同时累加边权
3
、
3、
3、一直重复(2),当加边的数量达到
n
−
1
n-1
n−1,算法结束
题目来源:poj1251Jungle Roads
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int maxn = 1000 + 10;
const int maxm = 1000 + 10;
struct node{
int u, v, w;
}e[maxm * 2];
int fa[maxn];
int n, m;
int find(int x){
if(fa[x] == x)
return x;
return fa[x] = find(fa[x]);
}
void init(){
m = 0;
for(int i = 1; i <= n; i++) fa[i] = i;
memset(e, 0, sizeof e);
}
bool cmp(node a, node b){
return a.w < b.w;
}
int kruskal(){
int res = 0, cnt = 0;
sort(e, e+m, cmp);
for(int i = 0; i < m; i++){
int fu = find(e[i].u);
int fv = find(e[i].v);
if(fu != fv){
fa[fu] = fv;
res += e[i].w;
if(++cnt >= n-1) //边的数量等于n-1
break;
}
}
return res;
}
int main()
{
int k ,w;
string u , v;
while(cin>>n, n){
init();
for(int i = 1; i < n; i++){
cin>>u>>k;
while(k--){
cin>>v>>w;
e[m].u = u[0] - 'A' + 1;
e[m].v = v[0] - 'A' + 1;
e[m++].w = w;
}
}
cout<<kruskal()<<endl;
}
return 0;
}