UVA 1515 Pool construction(网络流)

题意思路:见紫书,非常巧妙的网络流建图



#include<bits/stdc++.h>
using namespace std;
#define INF 1e9
const int maxn = 2505;
struct Edge
{
	int from,to,cap,flow;
	Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}
};
struct Dinic
{
	int n,m,s,t;
	vector<Edge>edges;
	vector<int> G[maxn];
	bool vis[maxn];
	int d[maxn];
	int cur[maxn];
	void AddEdge(int from,int to,int cap)
	{
		edges.push_back(Edge(from,to,cap,0));
		edges.push_back(Edge(to,from,0,0));
		m = edges.size();
		G[from].push_back(m-2);
		G[to].push_back(m-1);
	}
	void init(int n)
	{
		for (int i = 0;i<=n;i++)
			G[i].clear();
		edges.clear();
	}
	bool BFS()
	{
		memset(vis,0,sizeof(vis));
		queue<int>q;
		q.push(s);
		d[s]=0;
		vis[s]=1;
		while (!q.empty())
		{
			int x = q.front();
			q.pop();
			for (int i = 0;i<G[x].size();i++){
				Edge &e = edges[G[x][i]];
				if (!vis[e.to] && e.cap>e.flow){
					vis[e.to]=1;
					d[e.to]=d[x]+1;
					q.push(e.to);
				}
			}
		}
		return vis[t];
	}

	int DFS(int x,int a){
		if (x==t || a==0)
			return a;
		int flow = 0,f;
		for (int &i=cur[x];i<G[x].size();i++){
			Edge&e = edges[G[x][i]];
			if (d[x]+1==d[e.to] && (f=DFS(e.to,min(a,e.cap-e.flow)))>0){
				e.flow+=f;
				edges[G[x][i]^1].flow-=f;
				flow+=f;
				a-=f;
				if (a==0)
					break;
			}
		}
		return flow;
	}

	int Maxflow(int s,int t)
	{
		this->s=s;
		this->t=t;
		int flow = 0;
		while (BFS())
		{
			memset(cur,0,sizeof(cur));
			flow+=DFS(s,INF);
		}
		return flow;
	}
}di;
char str[60][60];
int dir[4][2]={{-1,0},{1,0},{0,1},{0,-1}};
int n,m,d,f,b;
bool check(int x,int y)
{
	return x>=1&&x<=n&&y>=1&&y<=m;
}
int main()
{
   int T;
   scanf("%d",&T);
   int cas=1;
   while (T--)
   {
	   int cnt =0;
	   scanf("%d%d",&m,&n);
	   scanf("%d%d%d",&d,&f,&b);
	   for (int i = 1;i<=n;i++)
	   {
		   scanf("%s",str[i]+1);
		   if (str[i][1]=='.')
		   {
			   ++cnt;
			   str[i][1]='#';
		   }
		   if (m>1 && str[i][m]=='.')
		   {
			   ++cnt;
			   str[i][m]='#';
		   }
		   if (i==1 || i==n)
			   for (int j = 1;j<=m;j++)
				   if (str[i][j]=='.')
				   {
					   ++cnt;
					   str[i][j]='#';
				   }
	   }
	   di.init(n*m+2);
	   for (int i = 1;i<=n;i++)
	   {
		   for (int j = 1;j<=m;j++)
		   {
			   for (int k = 0;k<4;k++)
			   {
				   int dx = i+dir[k][0];
				   int dy = j+dir[k][1];
				   if (check(dx,dy))
					   di.AddEdge((i-1)*m+j,(dx-1)*m+dy,b);
			   }
			   if (str[i][j]=='#')
			   {
				   if (i==1 || i==n || j==1 ||j==m)
					   di.AddEdge(0,(i-1)*m+j,INF);
				   else
					   di.AddEdge(0,(i-1)*m+j,d);
			   }
			   else
				   di.AddEdge((i-1)*m+j,n*m+1,f);
		   }
	   }
	   printf("%d\n",di.Maxflow(0,n*m+1)+cnt*f);
   }
}


You are working for the International Company for Pool Construction, a construction company which
specializes in building swimming pools. A new client wants to build several new pool areas.
A pool area is a rectangular grid of w × h square patches, consisting of zero or more (possibly
disconnected) pools. A pool consists of one or multiple connected hole patches, which will later be
filled with water. In the beginning, you start with a piece of land where each patch is either a hole in
the ground (’.’) or flat grass (’#’). In order to transform this land into a pool area, you must adhere
to the following:
• You can leave a patch as it is. This costs nothing.
• If the patch is grass in the beginning, you can dig a hole there. This costs d EUR.
• If the patch is a hole in the beginning, you can fill the hole and put grass on top. This costs f
EUR.
• You must place special boundary elements along each edge running between a final grass patch
and a final hole patch, to ensure that water does not leak from the pool. This costs b EUR per
boundary element.
• The outermost rows and columns of the pool area must always be grass.
You are given the task of calculating the cost of the cheapest possible pool area given the layout of
the existing piece of land.
Input
On the first line a positive integer: the number of test cases, at most 100. After that per test case:
• one line with two integers w and h (2 ≤ w, h ≤ 50): the width and height of the building site.
• one line with three integers d, f and b (1 ≤ d, f, b ≤ 10000): the costs for digging a new hole,
filling an existing hole, and building a boundary element between a pool and grass patch.
• h lines of w characters each, denoting the layout of the original building site.
Output
Per test case:
• one line with an integer: the cost of building the cheapest possible pool area from the original
piece of land.

Sample Input
3
3 3
5 5 1
#.#
#.#
###
5 4
1 8 1
#..##
##.##
#.#.#
#####
2 2
27 11 11
#.
.#
Sample Output
9
27
22

你可能感兴趣的:(UVA 1515 Pool construction(网络流))