《挑战程序设计竞赛》,初级篇–图
// Kruskal O(E*logV)
// Minimum Spanning Trees
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
#define maxv 101
#define maxe 101
#define INF 9999
/* union_find sets */
int par[maxv];
int rank[maxv];
void init(int n)
{
for(int i = 0; i < n; i++)
{
par[i] = i;
rank[i] = 0;
}
}
// 查询树的根
int find(int x)
{
if(par[x] == x)
return x;
else
return par[x] = find(par[x]);
}
// 合并x和y所属的集合
void unite(int x, int y)
{
x = find(x);
y = find(y);
if(x == y) return;
if(rank[x] < rank[y])
par[x] = y;
else
par[y] = x;
if(rank[x] == rank[y]) rank[x]++;
}
bool same(int x,int y)
{
return find(x) == find(y);
}
/* Kruskal */
struct edge
{
int u,v;
int cost;
};
bool cmp(const edge& e1, const edge& e2)
{
return e1.cost < e2.cost;
}
edge es[maxe];
int V,E;
int Kruskal()
{
sort(es, es+E, cmp);
init(V);
int res = 0;
for(int i = 0; i < E; i++)
{
edge e = es[i];
if(!same(e.u,e.v))
{
unite(e.u,e.v);
res += e.cost;
}
}
return res;
}
int main()
{
cin>>V>>E;
for(int i = 0; i < E; i++)
{
edge e;
cin>>e.u>>e.v>>e.cost;
es[i] = e;
}
cout<<"----------------"<<endl;
cout<<"最少花费为:"<<Kruskal();
return 0;
}
/*
测试数据:
5 6
0 1 1
0 2 3
1 2 4
1 4 6
2 3 2
2 4 1
*/