[bzoj1601]灌水
一道有趣的建图题,新建一个初始存在水的点,那么造井相当于向其连边,费用就是造井的费用,之后求最小生成树即可
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }