[bzoj1601]灌水

一道有趣的建图题,新建一个初始存在水的点,那么造井相当于向其连边,费用就是造井的费用,之后求最小生成树即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 struct ji{
 4     int x,y,z;
 5     bool operator < (const ji &k)const{
 6         return z<k.z;
 7     }
 8 }e[100005];
 9 int n,ans,f[305];
10 int find(int k){
11     if (k==f[k])return k;
12     return f[k]=find(f[k]);
13 }
14 int main(){
15     scanf("%d",&n);
16     for(int i=1;i<=n;i++){
17         scanf("%d",&e[i].z);
18         f[i]=e[i].y=i;
19     }
20     for(int i=1;i<=n;i++)
21         for(int j=1;j<=n;j++){
22             scanf("%d",&e[i*n+j].z);
23             e[i*n+j].x=i;
24             e[i*n+j].y=j;
25         }
26     sort(e+1,e+n*n+n+1);
27     for(int i=1;i<=n*n+n;i++)
28         if (find(e[i].x)!=find(e[i].y)){
29             f[find(e[i].x)]=find(e[i].y);
30             ans+=e[i].z;
31         }
32     printf("%d",ans);
33 }
View Code

 

posted @ 2019-11-08 16:06  PYWBKTDA  阅读(82)  评论(0编辑  收藏  举报