Bad Cowtractors (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
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 1500000
using 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 6
1 2 1
1 3 3
2 3 2
4 5 7
5 6 8
4 6 9
*/


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Kruskal算法是一种用来求加权连通图的最小生成树(MST)的算法,由Joseph Kruskal在1956年发表。该算法的基本思想是按照边的权值从小到大的顺序选择边,并保证这些边不构成回路。具体做法是首先构造一个只含有n个顶点的森林,然后依据权值从小到大从连通网中选择边加入到森林中,并保证森林中不产生回路,直至森林变成一棵树为止。 使用Kruskal算法求解最小生成树的过程主要有两个关键步骤。首先,需要对图的所有边按照权值大小进行排序。其次,需要判断在将边添加到最小生成树中时是否会形成回路。通过这两个步骤,Kruskal算法能够找到图的最小生成树。 总结来说,Kruskal算法通过按照边的权值从小到大选择边,并保证不形成回路的方式来构建最小生成树。这种算法适用于解决求解加权连通图的最小生成树问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Kruskal算法简易教程(附最全注释代码实现)](https://blog.csdn.net/hzf0701/article/details/107933639)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [克鲁斯卡尔算法(Kruskal)详解](https://blog.csdn.net/weixin_45829957/article/details/108001882)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值