POJ 2377 最大生成树之kruskal

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

题意:
心机老板不想给钱,心机员工就要让他走最长的路
N个谷仓,M条路 使仓库连通且路最长,求最长路之和,若谷仓不能连通,输出“-1”

思路:
类似并查集,查询各点的根节点,根不同则连接,相同则不操作。

代码如下:
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m;
int parent[10086];
struct node  //使用结构体数组来记录左右点与路长
{
    int l,r,w;
} a[100010];
bool cmp(node a,node b)   //对路长从大到小排序
{
    return a.w > b.w;
}
int root(int x)      //查找根结点
{
    if(parent[x]!=x)
    {
        parent[x]=root(parent[x]);
    }
    return parent[x];
}
int kruskal()    //主要函数
{
    sort(a,a+m,cmp);  //从大到小快排
    int sum=0;
    int x_root,y_root;
    for(int i=0; i<m; i++)
    {
        x_root=root(a[i].l);   //查找根结点
        y_root=root(a[i].r);
        if(x_root!=y_root)     //对根结点进行比较
        {
            parent[x_root]=y_root;  //根结点不同则将树连接同时记录路长
            sum+=a[i].w;
        }
    }
    
    return sum;
}
int main()
{
    while(cin>>n>>m)
    {
        int x,y,z;
        for(int i = 0;i < n;i++){     //初始化父节点数组
            parent[i] = i;
        }
        for(int i=0; i<m; i++)
        {
            cin>>x>>y>>z;
            a[i].l=x;
            a[i].r=y;
            a[i].w=z;
        }
        int sum=kruskal();
        int j=0;
        for(int i=0; i<n; i++)   //若根结点仍是自己则j++,根的根结点必然是自己 因此排除j==1
        {
            if(parent[i]==i)
                j++;
        }
        if(j>1)
        {
            cout<<-1<<endl;
        }
        else
            cout<<sum<<endl;
    }
}

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务