新的开始

发展采矿业当然首先得有矿井,小 FF 花了上次探险获得的千分之一的财富请人在岛上挖了 n 口矿井,但他似乎忘记考虑的矿井供电问题……
为了保证电力的供应,小 FF 想到了两种办法:
在这一口矿井上建立一个发电站,费用为 v(发电站的输出功率可以供给任意多个矿井)。
将这口矿井与另外的已经有电力供应的矿井之间建立电网,费用为 p。
小 FF 希望身为「NewBe_One」计划首席工程师的你帮他想出一个保证所有矿井电力供应的最小花费。


最小生成树的模板

但是我们有种非常好的思想,建立一个点,将所有的点都连到那个源点

所以为了保证图联通,肯定会有至少一条边连到了源点,也就是必定会有一个电源

然后因为最小生成树的性质,我们同时还解决了一个点新开电源比连电线更优的情况

下面给出代码:(变态压行)

#include<bits/stdc++.h>
using namespace std;
struct node{int u,v,w;}s[100006];
bool cmp(const node x,const node y){return x.w<y.w;}
int cnt=0,n,m,f[100006],ans=0,num=0,i,j;
int getf(int v){return f[v]==v?f[v]:f[v]=getf(f[v]);}
int main(){
    scanf("%d",&n);
    for(i=1;i<=n;i++) scanf("%d",&s[++cnt].w),s[cnt].u=i,s[cnt].v=n+1,f[i]=i;
    for(i=1;i<=n;i++) for(j=1;j<=n;j++) scanf("%d",&s[++cnt].w),s[cnt].u=i,s[cnt].v=j;
    sort(s+1,s+cnt+1,cmp);
    for(i=1;i<=cnt;i++){
        int h1=getf(s[i].u),h2=getf(s[i].v);
        if(h1!=h2) f[h2]=h1,ans+=s[i].w,num++;
    }
    printf("%d",ans);
    return 0;
}

 

posted @ 2018-10-24 20:38  Bruce--Wang  阅读(199)  评论(0编辑  收藏  举报