对于自己建水库的情况,新建一个虚拟结点,和其他点的边权即为自建水库的费用
这样问题就转化为一个裸最小生成树问题了。
这里用堆优化prim解决。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cctype> 5 #include<queue> 6 #define re register 7 using namespace std; 8 void read(int &x){ 9 char c=getchar();x=0; 10 while(!isdigit(c)) c=getchar(); 11 while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar(); 12 } 13 struct data{ 14 int d,u; 15 data(){} 16 data(int A,int B): 17 d(A),u(B) 18 {} 19 bool operator < (const data &tmp) const{return d>tmp.d;} 20 };priority_queue <data> h; 21 #define N 305 22 int n,a[N][N],d[N],ans; bool vis[N]; 23 int main(){ 24 read(n);++n; int k=0; 25 for(re int i=1;i<n;++i) 26 read(a[n][i]),a[i][n]=a[n][i];//新建边 27 for(re int i=1;i<n;++i) 28 for(re int j=1;j<n;++j) 29 read(a[i][j]); 30 memset(d,127,sizeof(d)); 31 h.push(data(d[1]=0,1)); 32 while(!h.empty()&&k<n){ 33 data x=h.top(); h.pop(); 34 if(vis[x.u]) continue; 35 vis[x.u]=1; ++k; ans+=x.d; 36 for(re int i=1;i<=n;++i) 37 if(a[x.u][i]){ 38 if(d[i]>a[x.u][i]){ 39 d[i]=a[x.u][i]; 40 h.push(data(a[x.u][i],i)); 41 } 42 } 43 }printf("%d",ans); 44 return 0; 45 }