zoukankan      html  css  js  c++  java
  • UVa1515 Pool construction 水塘 (NWERC2011)

    传送


    题面:输入一个(n)(m)列的字符矩阵,草地用#表示,洞用.表示。可以把草改成洞,每格花费(d),也可以把洞填上草,每格花费(f)。如果草和洞相邻,必须要在草洞之间修围栏,每条边花费(b)。整个矩阵第一行/列和最后一行/列必须都是草。问最小花费。


    这题如果练过一些最小割的相关模型就好做了。


    首先将地图中的每个格点看成图中的点,然后按照最小割的思想:在分割后的图中,和源点相连的点都是草,和汇点相连的点都是坑。
    那么只用考虑达成上述目标的代价:

    • 如果一个格点(x)是草,从(s)(x)连边,容量是修改成坑的费用(d),表示如果它不属于草的集合,就要付出(d)的代价。
    • 如果一个格点(x)是坑,从(x)(t)连边,容量是修改成草的费用(f),表示如果它不属于坑的集合,就要付出(f)的代价。
    • 对于相邻的格点,如果不相同,就连一条容量为(b)的边,代表如果草和坑都要保留,就必须修建一道代价为(b)的墙。
    • 对于最外圈的格点(x),直接记下修改成草的费用,并从(s)(x)连一条容量为无穷的边,表示改变他的代价是无穷大。

    最后跑最大流即答案。

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<vector>
    #include<queue>
    #include<assert.h>
    #include<ctime>
    using namespace std;
    #define enter puts("") 
    #define space putchar(' ')
    #define Mem(a, x) memset(a, x, sizeof(a))
    #define In inline
    #define forE(i, x, y) for(int i = head[x], y; ~i && (y = e[i].to); i = e[i].nxt)
    typedef long long ll;
    typedef double db;
    const int INF = 0x3f3f3f3f;
    const db eps = 1e-8;
    const int maxn = 2505;
    const int maxs = 55;
    const int maxe = 1e6 + 5;
    In ll read()
    {
    	ll ans = 0;
    	char ch = getchar(), las = ' ';
    	while(!isdigit(ch)) las = ch, ch = getchar();
    	while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
    	if(las == '-') ans = -ans;
    	return ans;
    }
    In void write(ll x)
    {
    	if(x < 0) x = -x, putchar('-');
    	if(x >= 10) write(x / 10);
    	putchar(x % 10 + '0');
    }
    
    char s[maxs][maxs];
    int n, m, d, f, b, S, t;
    struct Edge
    {
    	int nxt, to, cap, flow;
    }e[maxe];
    int head[maxn], ecnt = -1;
    In void addEdge(int x, int y, int w)
    {
    	e[++ecnt] = (Edge){head[x], y, w, 0};
    	head[x] = ecnt;
    	e[++ecnt] = (Edge){head[y], x, 0, 0};
    	head[y] = ecnt;
    }
    
    int sum = 0;
    int dx[] = {0, 0, 1, 0, -1}, dy[] = {0, 1, 0, -1, 0};
    In void buildGraph()
    {
    	sum = 0;
    	S = 0, t = n * m + 1;
    	for(int i = 1; i <= n; ++i)
    		for(int j = 1; j <= m; ++j)
    		{
    			int x = (i - 1) * m + j; 
    			if(i == 1 || i == n || j == 1 || j == m)
    			{
    				if(s[i][j] == '.') sum += f;
    				addEdge(S, x, INF);	
    			}
    			else 
    			{
    				if(s[i][j] == '.') addEdge(x, t, f);
    				else addEdge(S, x, d);
    			}
    			for(int k = 1; k <= 4; ++k)
    			{
    				int nx = i + dx[k], ny = j + dy[k];
    				if(nx && nx <= n && ny && ny <= m) addEdge(x, (nx - 1) * m + ny, b);
    			}
    		}
    }
    
    int dis[maxn];
    In bool bfs()
    {
    	Mem(dis, 0), dis[S] = 1;
    	queue<int> q; q.push(S);
    	while(!q.empty())
    	{
    		int now = q.front(); q.pop();
    		for(int i = head[now], v; ~i; i = e[i].nxt)
    			if(e[i].cap > e[i].flow && !dis[v = e[i].to])
    				dis[v] = dis[now] + 1, q.push(v);
    	}
    	return dis[t];
    }
    int cur[maxn];
    In int dfs(int now, int res)
    {
    	if(now == t || res == 0) return res;
    	int flow = 0, f;
    	for(int& i = cur[now], v; ~i; i = e[i].nxt)
    	{
    		if(dis[v = e[i].to] == dis[now] + 1 && (f = dfs(v, min(res, e[i].cap - e[i].flow))) > 0)
    		{
    			e[i].flow += f, e[i ^ 1].flow -= f;
    			flow += f, res -= f;
    			if(res == 0) break;
    		}
    	}
    	return flow;
    }
    In int minCut()
    {
    	int flow = 0;
    	while(bfs())
    	{
    		memcpy(cur, head, sizeof(head));
    		flow += dfs(S, INF);
    	}
    	return flow;
    }
    
    int main()
    {
    	int T = read();
    	while(T--)
    	{
    		Mem(head, -1), ecnt = -1;
    		m = read(), n = read();
    		d = read(), f = read(), b = read();
    		for(int i = 1; i <= n; ++i) scanf("%s", s[i] + 1);
    		buildGraph();
    		write(sum + minCut()), enter;
    	}
    	return 0;
    }
    
  • 相关阅读:
    TestNG超时测试
    iOS平台如何进行app自动化测试?
    软件性能测试见解与总结
    性能测试关注点整理总结
    测试用例的设计步骤
    如何建立软件测试管理体系?
    关于手工测试,应该如何做?
    web性能测试流程
    SPASVO推出ALM(覆盖全生命周期的研发过程管理平台)免费在线体验平台
    如何使用testcenter统计开发工程师工作质量?
  • 原文地址:https://www.cnblogs.com/mrclr/p/14901268.html
Copyright © 2011-2022 走看看