中文题面
国家电网决定在某个区域建设发电厂和电网。
这个区域有n座城市。国家电网对这些城市进行了调查,并建议将其中的m个城市作为发电厂的可能位置,第i个建议指出,国家电网可以在城市ci中建造一座发电厂,成本为ai。
这些发电厂非常现代化,一座发电厂就可以为整个区域供电,但修建电线是一件需要花钱的事情。输入一个数组b,当1≤ i<n时,bi表示在城市i和城市i+1之间建造电线的成本,bn表示在城市n和1之间建造电线的成本。如果一个城市包含一个发电厂,或者通过电线连接到一个有发电厂的城市,那么它将获得电力。
使区域内所有城市都获得电力的最便宜的供电方式是什么?
输入
第一行包含两个整数n(3≤ n≤ 1e5)和m(1≤ m≤ n),城市数量和发电厂的可能位置数量。
然后m行,第i行包含ci(1≤ ci≤ n) 及ai(1≤ ai≤ 1e9),发电厂的第i个可能位置以及建造成本。
最后一行包含n个整数bi(1≤ bi≤ 1e9),建设电线的成本。
c1,c2 ,…,cm的值是唯一的。
输出
输出区域内给所有城市供电的最低成本。
样例1
输入
3 2
1 100
2 200
150 300 150
输出
400
样例2
输入
3 2
1 100
2 200
300 300 150
输出
450
思路
添加一个新的点作为发电站,并将这个点与其他每个点都连一条边,这条边的权即在某个城市建立发电站的成本,然后就变成了一个最小生成树问题,使用kruskal算法即可。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
struct node {
int u,v,w;
bool operator< (node nod) {
return w<nod.w;
}
};
int n,m;
node nod[N];
int cnt,p[N];
int find(int x) {
if(p[x]!=x) p[x]=find(p[x]);
return p[x];
}
void kruskal() {
sort(nod,nod+cnt);
for (int i=1; i<=n+1; i++) p[i]=i;
long long ans=0;
for(int i=0;i<cnt;i++) {
int u=nod[i].u,v=nod[i].v,w=nod[i].w;
int pu=find(u),pv=find(v);
if(pu!=pv) {
p[pu]=pv;
ans+=w;
}
}
cout<<ans;
}
int main() {
cin>>n>>m;
while(m--) {
int c,a;
cin>>c>>a;
nod[cnt++]={n+1,c,a};
}
int w;
for(int i=1;i<n;i++) {
cin>>w;
nod[cnt++]={i,i+1,w};
}
cin>>w;
nod[cnt++]={1,n,w};
kruskal();
return 0;
}