Uva -1515 Pool construction(最小割)

输入一个字符矩阵,'.'代表洞,'#'代表草地。可以把草改成洞花费为d,或者把洞改成草花费为f,最后还要在草和洞之间修围栏花费为b。

首先把最外一圈的洞变成草,并累加花费。

增加一个源点和一个汇点,源点连接每个草地,汇点连接每个洞。

源点与最外一圈的草地连一条容量无穷大的边,与其他草地连一条容量为d的边。表示把这条弧切断,割的容量增加d,草就会变成洞。

每个洞与汇点连一条容量为f的边。

相邻两个格子之间连一条双向边。

用最大流算法求最小割在加上之前把边界上的洞变成草的费用,就是最小花费。

用最小的费用将对象划分成两个集合的问题常常可以转换成最小割顺利解决.这道题就可以考虑将每一个点变成草地和洞分成两个集合.

如果通过合适的建边使得花费的总和等价于割的容量的话,那么为了求最小花费只要求最小割就好.

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cmath>
  4 #include <vector>
  5 #include <cstring>
  6 #include <string>
  7 #include <algorithm>
  8 #include <string>
  9 #include <set>
 10 #include <functional>
 11 #include <numeric>
 12 #include <sstream>
 13 #include <stack>
 14 #include <map>
 15 #include <queue>
 16 #pragma comment(linker, "/STACK:102400000,102400000")
 17 #define CL(arr, val)    memset(arr, val, sizeof(arr))
 18 
 19 #define ll long long
 20 #define inf 0x7f7f7f7f
 21 #define lc l,m,rt<<1
 22 #define rc m + 1,r,rt<<1|1
 23 #define pi acos(-1.0)
 24 
 25 #define L(x)    (x) << 1
 26 #define R(x)    (x) << 1 | 1
 27 #define MID(l, r)   (l + r) >> 1
 28 #define Min(x, y)   (x) < (y) ? (x) : (y)
 29 #define Max(x, y)   (x) < (y) ? (y) : (x)
 30 #define E(x)        (1 << (x))
 31 #define iabs(x)     (x) < 0 ? -(x) : (x)
 32 #define OUT(x)  printf("%I64d
", x)
 33 #define lowbit(x)   (x)&(-x)
 34 #define Read()  freopen("a.txt", "r", stdin)
 35 #define Write() freopen("b.txt", "w", stdout);
 36 #define maxn 1010
 37 #define maxv 3000
 38 #define mod 1000000000
 39 using namespace std;
 40 
 41 struct edge
 42 {
 43     int to,cap,rev;
 44     edge(){}
 45     edge(int x,int y,int z)
 46     {
 47         to=x;
 48         cap=y;
 49         rev=z;
 50     }
 51 };
 52 
 53 vector<edge>G[maxv];
 54 int level[maxv];
 55 int iter[maxv];
 56 
 57 void Add_Edge(int from,int to,int cap)
 58 {
 59     G[from].push_back((edge){to,cap,G[to].size()});
 60     G[to].push_back((edge){from,0,G[from].size()-1});
 61 }
 62 
 63 void bfs(int s)
 64 {
 65     memset(level,-1,sizeof(level));
 66     queue<int>que;
 67     level[s]=0;
 68     que.push(s);
 69     while(!que.empty())
 70     {
 71         int v=que.front();que.pop();
 72         for(int i=0;i<G[v].size();i++)
 73         {
 74             edge &e=G[v][i];
 75             if(e.cap>0&&level[e.to]<0)
 76             {
 77                 level[e.to]=level[v]+1;
 78                 que.push(e.to);
 79             }
 80         }
 81     }
 82 }
 83 int dfs(int v,int t,int f)
 84 {
 85     if(v==t) return f;
 86     for(int &i=iter[v];i<G[v].size();i++)
 87     {
 88         edge &e=G[v][i];
 89         if(e.cap>0&&level[v]<level[e.to])
 90         {
 91             int d=dfs(e.to,t,min(f,e.cap));
 92             if(d>0)
 93             {
 94                 e.cap-=d;
 95                 G[e.to][e.rev].cap+=d;
 96               //  printf("%d %d %d
",e.to,e.rev,G[e.to][e.rev]);
 97                 return d;
 98             }
 99         }
100     }
101     return 0;
102 }
103 
104 int max_flow(int s,int t)
105 {
106     int flow=0;
107     for(;;)
108     {
109         bfs(s);
110         if(level[t]<0) return flow;
111         memset(iter,0,sizeof(iter));
112         int f;
113         while((f=dfs(s,t,inf))>0)
114         flow+=f;
115     }
116 }
117 char s[55][55];
118 int w,h;
119 int ID(int i,int j)
120 {
121     return i*w+j;
122 }
123 int main()
124 {
125     //freopen("a.txt","r",stdin);
126     int t,d,f,b;
127     scanf("%d",&t);
128     while(t--)
129     {
130         scanf("%d%d%d%d%d",&w,&h,&d,&f,&b);
131         for(int i=0;i<w*h+2;i++)
132             G[i].clear();
133         for(int i=0;i<h;i++)
134         {
135             scanf("%s",s[i]);
136         }
137         int cost=0;
138         for(int i=0;i<h;i++)
139         {
140             if(s[i][0]=='.') {s[i][0]='#';cost+=f;}
141             if(s[i][w-1]=='.') {s[i][w-1]='#';cost+=f;}
142         }
143         for(int i=0;i<w;i++)
144         {
145             if(s[0][i]=='.') {s[0][i]='#';cost+=f;}
146             if(s[h-1][i]=='.'){s[h-1][i]='#';cost+=f;}
147         }
148         for(int i=0;i<h;i++)
149         {
150             for(int j=0;j<w;j++)
151             {
152                 if(s[i][j]=='#')
153                 {
154                     int cap=inf;
155                     if(i>0&&i<h-1&&j>0&&j<w-1) cap=d;
156                     Add_Edge(w*h,ID(i,j),cap);
157                     if(i>0) {Add_Edge(ID(i,j),ID(i-1,j),b);}
158                     if(i<h-1) {Add_Edge(ID(i,j),ID(i+1,j),b);}
159                     if(j>0) {Add_Edge(ID(i,j),ID(i,j-1),b);}
160                     if(j<w-1) {Add_Edge(ID(i,j),ID(i,j+1),b);}
161                 }
162                 else
163                 {
164                     Add_Edge(ID(i,j),w*h+1,f);
165                     if(i>0) {Add_Edge(ID(i,j),ID(i-1,j),b);}
166                     if(i<h-1) {Add_Edge(ID(i,j),ID(i+1,j),b);}
167                     if(j>0) {Add_Edge(ID(i,j),ID(i,j-1),b);}
168                     if(j<w-1) {Add_Edge(ID(i,j),ID(i,j+1),b);}
169                 }
170             }
171         }
172         printf("%d
",cost+max_flow(w*h,w*h+1));
173     }
174     return 0;
175 }
原文地址:https://www.cnblogs.com/nowandforever/p/4603230.html