B - Shichikuji and Power Grid
题目:


题目网址:Problem - 1245D - Codeforces
思路:
给定n个城市要让这n个城市都通上电,可以在自己建电站,也可以去其他建立电站的城市接电线,求最少花费;
对数据进行预处理对所有费用数据进行排序从小到大;
然后在对从最小费用开始验算直到所有城市都有点,不能形成环,形成环跳过;
记录每一步操作,最后输出最小费用,以及通电城市,电线坐标;
代码实现:
#include<iostream> #include<algorithm> #include<stdio.h> #include<vector> #include<memory.h> typedef long long ll; using namespace std; const int mx=4e6+10; struct node{//存储操作的费用 int x,y; ll w; }s[mx]; vector<int>e[mx]; int f[mx],a[mx],b[mx],k[mx],vis[mx]; int n,tot,c,cnt; ll ans; void init(){//预处理操作 ans=cnt=0; tot=1; memset(vis,0,sizeof(vis)); for(int i=0;i<=n;i++) f[i]=i; } int find(int x)//查找是否满足条件 { return x==f[x]?f[x]:f[x]=find(f[x]); } bool cmp(node a,node b)//排序条件 { return a.w<b.w; } int main(){ scanf("%d",&n); init(); for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]); for(int i=1;i<=n;i++) { scanf("%d",&c); s[tot].x=0;//新增点0 s[tot].y=i;//在i点建电站 s[tot].w=c;//费用 tot++; } for(int i=1;i<=n;i++) scanf("%d",&k[i]); for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) { s[tot].x=i;//从i到j建电线的费用计算 s[tot].y=j; s[tot].w=1ll*(abs(a[i]-a[j])+abs(b[i]-b[j]))*(k[i]+k[j]); tot++; } } sort(s+1,s+tot,cmp);//对操作费用排序 for(int i=1;i<tot;i++)//从费用最小的进行验证直至满足条件 { int fx=find(s[i].x),fy=find(s[i].y); if(fx!=fy) { if(s[i].x==0) { vis[s[i].y]=1; cnt++; } else e[s[i].x].push_back(s[i].y); ans+=s[i].w; f[fy]=fx; } } printf("%lld\n",ans);//输出答案 printf("%d\n",cnt); for(int i=1;i<=n;i++) if(vis[i]) printf("%d ",i); printf("\n"); printf("%d\n",n-cnt); for(int i=1;i<=n;i++) { int p=e[i].size(); for(int j=0;j<p;j++) printf("%d %d\n",i,e[i][j]); } return 0; }

浙公网安备 33010602011771号