Bad Cowtractors (Kruskal)

来源:互联网 发布:淘宝联盟可以注销吗 编辑:程序博客网 时间:2024/06/16 02:25
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 81 2 31 3 72 3 102 4 42 5 83 4 63 5 24 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.

题意:

Bessie被雇来建立一个廉价的互联网网络,每个可能的连接路由都有一个相关的成本C(1 < = C=100000)。农场主约翰想花最少的钱来连接网络,他甚至不想付钱给Bessie。意识到农场主约翰不会付钱给她,Bessie决定尽可能做最糟糕的工作。她必须决定在一组连接安装,这些连接的总成本尽可能大。要在N个点之间连线,使总长度最长,不能有回路,如果不能连成树,则输出-1

代码:

#include<stdio.h>#include<string.h>#include<algorithm>#define MAX 1500000using namespace std;struct node{    int u,v,w;}e[MAX];       //存放边关系int pre[MAX];int n,m;int cmp(node a,node b){  //优先取最长的边    return a.w>b.w;}int Find(int x){    int r=x;              //寻找根结点    while(r!=pre[r])        r=pre[r];    int i=x,j;    while(i!=r){      //压缩路径        j=pre[i];        pre[i]=r;        i=j;    }    return r;}int mix(int a,int b){    int fa=Find(a),fb=Find(b);  //如果a,b这条边没加入到树里,则加入    if(fa!=fb){        pre[fb]=fa;        return 1;    }    return 0;}void init(){     //初始化pre    int i;    for(i=0;i<=n;i++){        pre[i]=i;    }}int main(){    memset(e,0,sizeof(e));    scanf("%d%d",&n,&m);    int t=1;    while(m--){          //获取边        int a,b,c;        scanf("%d%d%d",&a,&b,&c);        e[t].u=a;        e[t].v=b;        e[t++].w=c;    }    sort(e+1,e+t,cmp);  //按从大到小排序    init();    int i;    int cnt=0;    int sum=0;    for(i=1;i<t;i++){        if(mix(e[i].u,e[i].v)){  //每加入1条边cnt++            sum+=e[i].w;  //记录总长度            cnt++;        }    }    if(cnt==n-1) printf("%d\n",sum);  //如果加入的边为总点数少1 则形成树    else printf("-1\n");   return 0;}/*6 61 2 11 3 32 3 24 5 75 6 84 6 9*/