B - Super Mancunian

该博客介绍了如何运用最小生成树算法解决一个与图论相关的问题,即在给定的等级之间存在费用,目标是最小化访问所有等级的总花费。通过先找到最小生成树的最小边权和最大边权,然后调整图中的边来减少总成本,最终得出在不形成环路的情况下访问所有等级的最低费用以及可能的不同生成树数量。
摘要由CSDN通过智能技术生成

题目链接

题意:有n个等级,某些等级是相连的,但需要费用w才可以解锁访问,解锁之后再次访问该等级不需要任何花费,从等级1开始,访问n个等级花费的最小值,另外一个条件是可以让某两个等级之间的花费变为0。
思路:先用最小生成树求一下最小边权之和与最小生成树中的最大边权值maxx,再用类似最小生成树的方法求一下,在不成环的前提下,如果边权值>=maxx的边并且加上这条边能构成最小生成树,那么tot++(tot最小生成树的个数);否则就让u的父节点归结于v的父节点。继续遍历。

注意要是用long long,代码中将long long用int代替了。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <queue>
#define int long long
#define lowbit(x) ((~x+1)&x)
using namespace std;
const int N = 5e5+10;
struct node {
    int u,v,w;
}a[N];
int cnt,f[N],val[N];
int n,m,k;
int ans,maxx;
int u,v,w;

bool cmp(node a,node b) {
    return a.w<b.w;
}

int Find(int x) {
    if(x!=f[x]) {
        f[x] = Find(f[x]);
    }
    return f[x];
}

void join(int u,int v,int w) {
    int x = Find(u);
    int y = Find(v);
    if(x!=y) {
        f[x] = y;
        maxx = w;
        k++;
        ans+=w;
    }
}

signed main() {
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1; i<=n; i++) f[i] = i;
    for(int i=1; i<=m; i++) {
        cin>>u>>v>>w;
        a[i].u = u;
        a[i].v = v;
        a[i].w = w;
    }
    sort(a+1,a+m+1,cmp);
    int i=1;
    while(k<n-1) {
        join(a[i].u,a[i].v,a[i].w);
        i++;
    }
    for(int i=1; i<=n; i++) f[i] = i;
    int tot=0;
    for(int i=1; i<=m; i++) {
        if(Find(a[i].u)!=Find(a[i].v)) {
            if(a[i].w>=maxx) {
                tot++;
            }
            else {
                f[Find(a[i].u)] = Find(a[i].v);
            }
        }
    }
    cout<<ans-maxx<<' '<<tot<<endl;
    return 0;
}

代码参考于https://blog.csdn.net/luoxutimberjack/article/details/104303560

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值