acw 1146. 新的开始[最小生成树之超级源点应用]

发展采矿业当然首先得有矿井,小 FF 花了上次探险获得的千分之一的财富请人在岛上挖了 n 口矿井,但他似乎忘记了考虑矿井供电问题。

为了保证电力的供应,小 FF 想到了两种办法:

在矿井 i 上建立一个发电站,费用为 vi(发电站的输出功率可以供给任意多个矿井)。 将这口矿井 i 与另外的已经有电力供应的矿井 j
之间建立电网,费用为 pi,j。 小 FF 希望你帮他想出一个保证所有矿井电力供应的最小花费方案。

输入格式: 第一行包含一个整数 n,表示矿井总数。

接下来 n 行,每行一个整数,第 i 个数 vi 表示在第 i 口矿井上建立发电站的费用。

接下来为一个 n×n 的矩阵 P,其中 pi,j 表示在第 i 口矿井和第 j 口矿井之间建立电网的费用。

数据保证 pi,j=pj,i,且 pi,i=0。

输出格式: 输出一个整数,表示让所有矿井获得充足电能的最小花费。

数据范围 1≤n≤300, 0≤vi,pi,j≤105

像这种 找总体代价最小的问题 考虑到MST,每个点又带权值,并且含有边权,想到超级源点。
我们假设存在一个超级发电站,并且设每个点与这个超级源点存在一条边,边权就是建设这个点的代价,那么我直接跑MST使得每个点通电的最小代价就行啦
这个题意思并不是只能建一个发电站,可以有很多个连通块,最后使得每个点都能发电即可
例如:
在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+7;
struct node{
    int from,to,d;
}s[N];
int cnt=0;
int cmp(const node s1,const node s2){
    return s1.d<s2.d;
}
int father[N];
int find(int x){
    if(x==father[x]) return x;
    return father[x]=find(father[x]);
}

int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++) father[i]=i;
    for(int i=1;i<=n;i++){
        int v;cin>>v;
        s[++cnt]={i,n+1,v};
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            int x;
            cin>>x;
            if(i>j) s[++cnt]={i,j,x};
        }
    }
    sort(s+1,s+1+cnt,cmp);
    int res=0;
    for(int i=1;i<=cnt;i++){
        int a=s[i].from,b=s[i].to,w=s[i].d;
        int dx=find(a),dy=find(b);
        if(dx!=dy){
            father[dx]=dy;
            res+=w;
        }
    }
    cout<<res<<endl;
    return 0;
}

水篇题解TAT

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值