码迷,mamicode.com
首页 > 其他好文 > 详细

UVa 1515 Pool construction (最小割)

时间:2017-05-19 22:14:10      阅读:307      评论:0      收藏:0      [点我收藏+]

标签:nbsp   pre   names   string   option   ++   class   stream   ...   

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=528&page=show_problem&problem=3916

题目大意:给定一个h*w的矩阵,每格是草地(#)或洞(.),可以花费d把一个#变成.,也可以花费f把一个.变成#,最后相邻的#和.之间要隔一个栅栏,每个花费为b.最后边界上必须全部是#,求最少花费.

分析:- - 感觉不容易想到...首先由分隔开#和.以及花费最少,联想到最小割.设置一个s,一个t,s连所有#,权重为d,若#变成.,即把这个点分到T中去,需要把这条边割断;所有.连到t,权重为f;相邻点互相连一条边,权重为b,最后如果一个在S一个在T,则需要把这条边割断.还有边界需要是草地,故把s连到边界,权值设为无穷.最后求一下从s到t的最小割即可.

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<vector>
 5 #include<queue>
 6 typedef long long ll;
 7 using namespace std;
 8 const int maxn=2550,maxm=25500,INF=1000000;
 9 int w,h,d,f,b;
10 
11 struct Edge{
12     int from,to,cap,flow;
13     Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}
14 };
15 
16 struct EdmondsKarp{
17     int n,m;
18     vector<Edge> edges;
19     vector<int> G[maxn];
20     int p[maxn],a[maxn];
21 
22     void init(int _n){
23         this->n=n;
24         this->m=0;
25         for(int i=0;i<maxn;i++)G[i].clear();
26         edges.clear();
27     }
28 
29     void AddEdge(int from,int to,int cap,int flow){
30         edges.push_back(Edge(from,to,cap,flow));
31         edges.push_back(Edge(to,from,0,flow));
32         G[from].push_back(m++);
33         G[to].push_back(m++);
34     }
35 
36     ll Maxflow(int s,int t){
37         ll flow=0;
38         while(1){
39             memset(a,0,sizeof(a));
40             queue<int>Q;
41             Q.push(s);
42             a[s]=INF;
43             while(!Q.empty()){
44                 int x=Q.front();Q.pop();
45                 for(int i=0;i<G[x].size();i++){
46                     Edge &e=edges[G[x][i]];
47                     if(!a[e.to]&&e.cap>e.flow){
48                         p[e.to]=G[x][i];
49                         a[e.to]=min(a[x],e.cap-e.flow);
50                         Q.push(e.to);
51                     }
52                 }
53                 if(a[t])break;
54             }
55             if(!a[t])break;
56             for(int u=t;u!=s;u=edges[p[u]].from){
57                 edges[p[u]].flow+=a[t];
58                 edges[p[u]^1].flow-=a[t];
59             }
60             flow+=a[t];
61         }
62         return flow;
63     }
64 };
65 
66 int main(){
67     int kase;
68     long long ans=0;
69     cin>>kase;
70     while(kase--){
71         ans=0;
72         cin>>w>>h;
73         cin>>d>>f>>b;
74         EdmondsKarp ek;
75         ek.init(w*h+2);
76         char c;
77         for(int i=0;i<w*h;i++){
78             cin>>c;
79             if(i/w==0||i/w==h-1||i%w==0||i%w==w-1){
80                 if(c!=#)ans+=f;
81                 ek.AddEdge(w*h,i,INF,0);
82             }
83             else if(c==#)ek.AddEdge(w*h,i,d,0);
84             else ek.AddEdge(i,w*h+1,f,0);
85             if(i>0&&(i-1)/w==i/w)ek.AddEdge(i,i-1,b,0);
86             if(i<w*h&&(i+1)/w==i/w)ek.AddEdge(i,i+1,b,0);
87             if(i-w>=0)ek.AddEdge(i,i-w,b,0);
88             if(i+w<w*h)ek.AddEdge(i,i+w,b,0);
89         }
90         ans+=ek.Maxflow(w*h,w*h+1);
91         cout<<ans<<endl;
92     }
93     return 0;
94 }

 

UVa 1515 Pool construction (最小割)

标签:nbsp   pre   names   string   option   ++   class   stream   ...   

原文地址:http://www.cnblogs.com/7391-KID/p/6880268.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!