当前位置: 代码迷 >> 综合 >> POJ 2377 Bad Cowtractors 最大生成树 Kruskal
  详细解决方案

POJ 2377 Bad Cowtractors 最大生成树 Kruskal

热度:17   发布时间:2023-12-20 23:32:23.0

Description
Bessie has been hired to build a cheap internet network among Farmer John’s N (2 <= N <= 1,000) barns that are conveniently numbered 1…N. FJ has already done some surveying, and found M (1 <= M <= 20,000) possible connection routes between pairs of barns. Each possible connection route has an associated cost C (1 <= C <= 100,000). Farmer John wants to spend the least amount on connecting the network; he doesn’t even want to pay Bessie.
Realizing Farmer John will not pay her, Bessie decides to do the worst job possible. She must decide on a set of connections to install so that (i) the total cost of these connections is as large as possible, (ii) all the barns are connected together (so that it is possible to reach any barn from any other barn via a path of installed connections), and (iii) so that there are no cycles among the connections (which Farmer John would easily be able to detect). Conditions (ii) and (iii) ensure that the final set of connections will look like a “tree”.
Input
Line 1: Two space-separated integers: N and M
Lines 2…M+1: Each line contains three space-separated integers A, B, and C that describe a connection route between barns A and B of cost C.
Output
Line 1: A single integer, containing the price of the most expensive tree connecting all the barns. If it is not possible to connect all the barns, output -1.
Sample Input
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
Sample Output
42
Hint
OUTPUT DETAILS:
The most expensive tree has cost 17 + 8 + 10 + 7 = 42. It uses the following connections: 4 to 5, 2 to 5, 2 to 3, and 1 to 3.

题目大意:
给出每条边的端点和权值,使他们生成一个树,且权值之和最大,即求最大生成树。

思路:先将每条边按权值从大到小排列,然后使用Kruskal算法。
注意该题目需要判断一下存不存在生成树。
AC代码:

#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
#define INF 0x3fffffff
#define maxn 1001
int n, m;//顶点个数 边的个数
struct edge {
    int u, v, w;
}e[20001];
bool cmp(edge a, edge b) {
     return a.w > b.w; }
int tree[maxn];
int findroot(int a) {
    if (tree[a] == -1)return a;else {
    int tmp = findroot(tree[a]);tree[a] = tmp;//路径压缩return tmp;}
}
bool hebing(int a, int b) {
    a = findroot(a);b = findroot(b);if (a != b) {
    tree[a] = b;return true;}return false;
}
void init(int x) {
    for (int i = 1; i <= x; i++) {
    tree[i] = -1;}
}
int main() {
    while (scanf("%d%d", &n, &m) != EOF) {
    if (n == 0)break;init(n);for (int i = 1; i <= m; i++) {
    scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].w);}sort(e + 1, e + 1 + m, cmp);int ans = 0; int num = 1;//num是已经连通的结点数for (int i = 1; i <= m; i++) {
    if (hebing(e[i].u, e[i].v)) {
    ans += e[i].w;num++;}}//判断是否存在生成树if (num==n) cout << ans << endl;else cout << -1 << endl;}return 0;
}