Kruskal
【问题描述】
图里有N个点M条边,求最大生成树。
【输入格式】
第一行:两个整数 N M
下面M行:每行3个整数 A,B,C。表示连接A、B两个点的费用是C。
【输出格式】
表示生成最大生成树的总费用。
【输入样例】
5 8
1 2 3
1 3 7
2 3 10
2 4 4
2 5 8
3 4 6
3 5 2
4 5 17
【输出样例】
42
【数据规模】
对于100%的数据满足:2<= N <= 1000,1<= M <= 20,000,1<= C <=100,000
code
#include<iostream>
#include<algorithm>
#include<cstdio>
#define MAXN 233333
using namespace std;
int fa[MAXN], noderank[MAXN];
void union_find_init(int v)
{
for (int i = 1; i <= v; i++)
{
fa[i] = i;
noderank[i] = 0;
}
}
int find(int x)
{
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
void unite(int x, int y)
{
x = find(x);
y = find(y);
if (x == y) return;
if (noderank[x] < noderank[y]) fa[x] = y;
else
{
fa[y] = x;
if (noderank[x] == noderank[y]) noderank[x] ++;
}
}
bool same(int x, int y)
{
return find(x) == find(y);
}
struct edge
{
int u;
int v;
int cost;
};
bool cmp(edge e1,edge e2)
{
return e1.cost>e2.cost;
}
#define MAXN 23333
edge es[MAXN];
int v,e,cnt;
int kruskal()
{
sort(es,es+e,cmp);
union_find_init(v);
int res = 0;
for(int i=0;i<e;i++)
{
edge ee=es[i];
if(!same(ee.u,ee.v))
{
unite(ee.u,ee.v);
res+=ee.cost;
cnt++;
if(cnt==v-1)
return res;
}
}
return -1;
}
int main()
{
scanf("%d%d",&v,&e);
for(int i=0;i<e;i++)
scanf("%d%d%d",&es[i].u,&es[i].v,&es[i].cost);
cout<<kruskal();
}