码题集-供水管线

题目

  在n个城市之间原本要规划修建许多条下水管道,管理人员发现这些管道会形成一条回 路,而下水道只要将城市联通即可,所以回路会加大施工的成本。所以希望你来帮忙找 出多余的管道来进行优化。当然管道和管道之间是有区别的,比如用s来表示i到j 的管道管理费用,8i越小则表示该管道管理费用越低。能否去除一些管线,使得总管理 成本最低。求出最低的管理成本(不存在自身与自身成为回路的管道)。

格式

输入格式:

第一行有两个数n和k表示城市数量和管道数量;

输出格式:

一个正整数,最低管理成本。 接下来k行,每行都有三个数i,j,c表示城市i和城市j之间的管道成本为c。

样例

输入:

3 3
1 2 3
1 3 5
2 3 8

输出:

8

备注

其中1<n,k<100

代码

    本题的知识点为并查集+kruskal算法,先将边进行从大到小的排序,然后依次加入到生成树中。加入时要通过并查集判断两个顶点是否位于同一个集合当中,如果是,则会构成回路,不加入;如果不是,则加入,同时更新并查集。

#include <bits/stdc++.h>
using namespace std;
const int N=1e2+7;
struct NODE{
    int i,j,c;
    bool operator<(const NODE &t) const {return c<t.c;}
}p[N];
//并查集工作
int fa[N],n,k,ans;
void init()    //初始时候每一点都是一个集合,这里的fa[i]是表示不同的点处于孤立状态
{
    for(int i=1;i<N;i++)
    {
        fa[i]=i;
    }
}
int find(int x)  //fa[x]不等于x了,表明x已经不是初始的孤立状态了,已经经过合并进入别的集合了,这时要找出x的集合
{
    return x==fa[x]?x:(fa[x]=find(fa[x]));      //fa[x]=find(fa[x])很好理解,就是再去找出fa[x]所在的集合
}
void mer(int x,int y)  //并查集的合并操作
{
    x=find(x),y=find(y);
    if(x!=y)
    {
        fa[x]=y;
    }
}
int main()
{
    init();
    cin>>n>>k;    //n为城市数量,k为管道数量
    for(int i=0;i<k;i++)
    {
        cin>>p[i].i>>p[i].j>>p[i].c;
    }
    sort(p,p+k);   //以边权重对管道进行排序
    for(int i=0;i<k;i++)
    {
        if(find(p[i].i)!=find(p[i].j))
        {
            ans+=p[i].c;
            mer(p[i].i,p[i].j);
        }
    }
    cout<<ans;
    return 0;




}

ps:本题解题过程中参考了b站up主:轩哥码题,大家详情可看up的视频,附上up讲题视频链接:【码蹄集进阶塔全题解13】数据结构:并查集/线段树/树状数组 MT2137 – MT2143_哔哩哔哩_bilibili

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值