给水
温馨提示
(不要以为是题 水题)
题目大意
- 就是有N个草地,要为它们引水,可以在该草地处建立一口井,也可以建立管道从别的草地引水进来,问最少需要花费多少才能保证每个草地都有水
输入样例
4
5
4
4
3
0 2 2 2
2 0 3 3
2 3 0 4
2 3 4 0
输出样例
9
提示
- 【样例解释】
FJ可以在草地4建井,并把草地2,3,4与草地1之间建立管道,花费为3+2+2+2=9
解题思路
- 其实这道题就是一道贪心,建立一个点,然后把所有的点和新点连上,费用就是建立井的费用,再跑一边最小生成树即可.
程序如下
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,a[10001],b[10001],f[1001][1001],ans,s;
bool t[1001];
int main()
{
//freopen("water.in","r",stdin);
//freopen("water.out","w",stdout);
scanf("%d",&n);
m=n+1;
for(int i=1;i<=n;++i)
scanf("%d",&a[i]);
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
scanf("%d",&f[i][j]);
for(int i=1;i<=m;++i)
f[i][m]=f[m][i]=a[i];//连边
memset(b,0x7f,sizeof(b));
b[1]=0;//初始值
for(int i=1;i<=m;++i)
{
s=0;
for(int j=1;j<=m;++j)
{
if(b[j]<b[s]&&!t[j]) //更优的点
s=j;
}
ans+=b[s];
t[s]=true;
for(int k=1;k<=m;++k)//更改数值
{
if(s!=k&&f[s][k]<b[k])
b[k]=f[s][k];
}
}
printf("%d",ans);
return 0;
}