【bzoj1601】【uscao2008 oct】【灌水】【最小生成树】

来源:互联网 发布:乐宝是什么软件 编辑:程序博客网 时间:2024/05/01 20:16

Description

Farmer John已经决定把水灌到他的n(1<=n<=300)块农田,农田被数字1到n标记。把一块土地进行灌水有两种方法,从其他农田饮水,或者这块土地建造水库。 建造一个水库需要花费wi(1<=wi<=100000),连接两块土地需要花费Pij(1<=pij<=100000,pij=pji,pii=0). 计算Farmer John所需的最少代价。

Input

*第一行:一个数n

*第二行到第n+1行:第i+1行含有一个数wi

*第n+2行到第2n+1行:第n+1+i行有n个被空格分开的数,第j个数代表pij。

Output

*第一行:一个单独的数代表最小代价.

Sample Input

4
5
4
4
3
0 2 2 2
2 0 3 3
2 3 0 4
2 3 4 0

Sample Output

9


输出详解:

Farmer John在第四块土地上建立水库,然后把其他的都连向那一个,这样就要花费3+2+2+2=9

题解:建立一个额外点T,每个土地向它连权值为建水库的边.然后跑最小生成树即可.

代码:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define N 500 using namespace std;struct use{  int st,en,v;}e[N*N]; int T,n,fa[N],x,y,v,map[N][N],cnt,ans;int find(int x){  if (fa[x]!=x) fa[x]=find(fa[x]);  return fa[x];} bool cmp(use a,use b){  return a.v<b.v;}int main(){  scanf("%d",&n);T=n+1;  for (int i=1;i<=n+1;i++) fa[i]=i;  for (int i=1;i<=n;i++) scanf("%d",&v),e[++cnt].st=i,e[cnt].en=T,e[cnt].v=v;  for (int i=1;i<=n;i++)   for (int j=1;j<=n;j++)      scanf("%d",&map[i][j]);  for (int i=1;i<=n;i++)    for (int j=i+1;j<=n;j++)      e[++cnt].st=i,e[cnt].en=j,e[cnt].v=map[i][j];  sort(e+1,e+cnt+1,cmp);    for (int i=1;i<=cnt;i++){    int r1=find(e[i].st),r2=find(e[i].en);    if (r1!=r2){      fa[r1]=r2;      ans+=e[i].v;     }   }  cout<<ans<<endl;} 


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 一元二次方程应用题 一元一次方程应用题 分数混合运算应用题 分段计费问题应用题 二年级加减法应用题 三年级加减法应用题 四年级解方程应用题 二年级上数学应用题 二年级乘除法应用题 2年级下册数学应用题 七年级上数学应用题 三年级上册数学应用题 二年级下册数学应用题 四年级上册数学应用题 四年级上册数学应用题100道 五年级上册数学应用题 小学二年级数学应用题 二年级数学下册应用题大全 三年级下册数学应用题 小学六年级数学应用题 六年级下册数学应用题 七年级上册数学应用题 四年级鸡兔同笼应用题 五年级小数除法应用题 五年级下册数学应用题 三年级上期数学应用题 小学三年级时间应用题 小学二年级数学应用题大全 小学三年级数学应用题上册 六年级工程问题应用题 六年级数学比例应用题 六年级数学工程应用题 五年级鸡兔同笼应用题 10以内的加减法应用题 五年级上册小数除法应用题 小学二年级数学应用题上册 小学三年级上册数学应用题 二年级数学除法应用题 小学二年级除法应用题 二年级下册奥数应用题 七年级数学方程应用题