bzoj1601 / P1550 [USACO08OCT]打井Watering Hole(堆优化prim)

 

 
对于自己建水库的情况,新建一个虚拟结点,和其他点的边权即为自建水库的费用
这样问题就转化为一个裸最小生成树问题了。
这里用堆优化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 }
View Code

 

posted @ 2018-10-25 15:44  kafuuchino  阅读(109)  评论(0编辑  收藏  举报