题意:给出一个图,求出其中的最大生成树= =如果无法产生树,输出-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 ", 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; }