标签:n+1 time 卡尔 name script ram 财富 格式 电力
发展采矿业当然首先得有矿井,小 FF 花了上次探险获得的千分之一的财富请人在岛上挖了 nnn 口矿井,但他似乎忘记考虑的矿井供电问题……
为了保证电力的供应,小 FF 想到了两种办法:
小 FF 希望身为「NewBe_One」计划首席工程师的你帮他想出一个保证所有矿井电力供应的最小花费。
第一行一个整数 nnn,表示矿井总数。
第 2~n+12\sim n+12~n+1 行,每行一个整数,第 iii 个数 viv_iv?i?? 表示在第 iii 口矿井上建立发电站的费用。
接下来为一个 n×nn\times nn×n 的矩阵 ppp,其中 pi,jp_{i,j}p?i,j?? 表示在第 iii 口矿井和第 jjj 口矿井之间建立电网的费用(数据保证有pi,j=pj,ip_{i,j}=p_{j,i}p?i,j??=p?j,i??,且 pi,i=0p_{i,i}=0p?i,i??=0)。
输出仅一个整数,表示让所有矿井获得充足电能的最小花费。
4
5
4
4
3
0 2 2 2
2 0 3 3
2 3 0 4
2 3 4 0
9
小 FF 可以选择在 444 号矿井建立发电站然后把所有矿井都不其建立电网,总花费是 3+2+2+2=93+2+2+2=93+2+2+2=9。
分析:这道题原来用的克鲁斯卡尔算法(最小生成树+最小v[i]),在LOJ上最多得了50分。其实它可能出现一个矿井修电网还不如修电站的情况,故改用Prim算法
#include<bits/stdc++.h> using namespace std; int a[1000][1000],v[1000]; int dis[10000]; bool book[10000]; #define inf 1e12; int main() { int n; cin>>n; for(int i=1;i<=n;i++) { cin>>v[i]; a[i][n+1]=v[i]; a[n+1][i]=v[i]; } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) cin>>a[i][j]; memset(book,0,sizeof book); for(int k=1;k<=n+1;k++) { dis[k]=a[1][k]; } book[1]=1; int ans=0; for(int k=1;k<=n;k++) { long long mins=inf; int minj; for(int j=1;j<=n+1;j++) { if(!book[j]&&dis[j]<mins) { mins=dis[j]; minj=j; } } book[minj]=1; ans+=dis[minj]; for(int j=1;j<=n+1;j++) if(book[j]==0&&dis[j]>a[minj][j]) dis[j]=a[minj][j]; } cout<<ans; }
标签:n+1 time 卡尔 name script ram 财富 格式 电力
原文地址:https://www.cnblogs.com/719666a/p/9526385.html