POJ 2377 Bad Cowtractors (Kruskal)

题意:给出一个图,求出其中的最大生成树= =如果无法产生树,输出-1。

思路:将边权降序再Kruskal,再检查一下是否只有一棵树即可,即根节点只有一个

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

int N, M; // 节点,边的数量
struct edge {
	int from, to, dist;
	bool operator<(const edge &b) const {
		return dist > b.dist;
	}
} es[20006];
int par[1005];
void init() {
	for (int i = 1; i <= N; ++i) par[i] = i;
}
int find(int x) {
	return x == par[x] ? x : par[x] = find(par[x]);
}
void unite(int x, int y) {
	x = find(x);
	y = find(y);
	if (x != y) par[x] = y;
}
int kruskal() {
	int res = 0;
	init();
	sort(es + 1, es + 1 + M);
	for (int i = 1; i <= M; ++i) {
		edge e = es[i];
		//printf("u:%d v:%d d:%d\n", e.from, e.to, e.dist);
		if (find(e.from) != find(e.to)) {
			unite(e.from, e.to);
			res += e.dist;
		}
	}
	return res;
}
void solve() {
	int res = kruskal();
	int cnt = 0;
	for (int i = 1; i <= N; ++i)
	if (find(i) == i) ++cnt; // 求出根节点数,如果最终结果为一棵树,那么根节点只有一个
	if (cnt != 1)  // 根节点数为1才能形成树
		cout << -1 << endl;
	else
		cout << res << endl;
}
int main()
{
	int u, v, d;
	while (cin >> N >> M) {
		for (int i=1; i <= M; ++i)
		{
			cin >> u >> v >> d;
			es[i].from = u;
			es[i].to = v;
			es[i].dist = d;
		}
		solve();
	}
	return 0;
}
posted @ 2017-08-20 16:37  demianzhang  阅读(204)  评论(0编辑  收藏  举报