• BZOJ2150 部落战争 【带上下界最小流】


    题目链接

    BZOJ2150

    题解

    复习:
    带上下界网络流两种写法:

    1. 不建(T->S)(INF)的边,即不考虑源汇点,先求出此时超级源汇的最大流,即无源汇下最大的自我调整,再加入该边,求超级源汇最大流增加的流量
    2. 先求出【或观察出】(S->T)的最大流,记为(tot),然后撤销流量,再建立(T->S),求出超级源汇最大流(f),答案为(tot - f)

    两者本质一样,但后者在(S->T)最大流确定的情况下,可以增加效率

    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<cmath>
    #include<map>
    #define LL long long int
    #define REP(i,n) for (int i = 1; i <= (n); i++)
    #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
    #define cls(s,v) memset(s,v,sizeof(s))
    #define mp(a,b) make_pair<int,int>(a,b)
    #define cp pair<int,int>
    using namespace std;
    const int maxn = 5005,maxm = 3000005,INF = 0x3f3f3f3f;
    inline int read(){
    	int out = 0,flag = 1; char c = getchar();
    	while (c < 48 || c > 57){if (c == '-') flag = 0; c = getchar();}
    	while (c >= 48 && c <= 57){out = (out << 1) + (out << 3) + c - 48; c = getchar();}
    	return flag ? out : -out;
    }
    char sq[55];
    int X[] = {1,1},Y[] = {-1,1};
    int N,M,R,C,id[55][55],tot;
    int S,T,q[maxn],head,tail,cur[maxn];
    int now,used[maxn],vis[maxn],d[maxn];
    int h[maxn],ne = 1;
    struct EDGE{int to,nxt,f;}ed[maxm];
    inline void build(int u,int v,int f){
    	ed[++ne] = (EDGE){v,h[u],f}; h[u] = ne;
    	ed[++ne] = (EDGE){u,h[v],0}; h[v] = ne;
    }
    bool bfs(int S,int T){
        q[head = tail = 0] = S; vis[S] = ++now;
        int u;
        while (head <= tail){
            u = q[head++];
            Redge(u) if (ed[k].f && vis[to = ed[k].to] != now){
                d[to] = d[u] + 1;
                vis[to] = now;
                q[++tail] = to;
                if (to == T) return true;
            }
        }
        return false;
    }
    int dfs(int u,int minf,int T){
        if (u == T || !minf) return minf;
        int f,flow = 0,to;
        if (used[u] != now) used[u] = now,cur[u] = h[u];
        for (int& k = cur[u]; k; k = ed[k].nxt)
            if (vis[to = ed[k].to] == now && d[to] == d[u] + 1 && (f = dfs(to,min(minf,ed[k].f),T))){
                ed[k].f -= f; ed[k ^ 1].f += f;
                flow += f; minf -= f;
                if (!minf) break;
            }
        return flow;
    }
    int main(){
    	N = read(); M = read(); R = read(); C = read();
    	REP(i,N){
    		scanf("%s",sq + 1);
    		REP(j,M) if (sq[j] == '.') id[i][j] = ++tot;
    	}
    	S = (tot << 1) + 1; T = S + 1;
    	REP(i,N) REP(j,M){
    		if (!id[i][j]) continue;
    		int x,y,u = id[i][j];
    		build(S,u + tot,1); build(u,T,1);
    		for (int k = 0; k < 2; k++){
    			x = i + X[k] * R;
    			y = j + Y[k] * C;
    			if (x < 1 || y < 1 || x > N || y > M || !id[x][y]) continue;
    			build(u + tot,id[x][y],1);
    		}
    		if (R != C){
    			for (int k = 0; k < 2; k++){
    				x = i + X[k] * C;
    				y = j + Y[k] * R;
    				if (x < 1 || y < 1 || x > N || y > M || !id[x][y]) continue;
    				build(u + tot,id[x][y],1);
    			}
    		}
    	}
    	int ans = tot;
    	while (bfs(S,T)) ans -= dfs(S,INF,T);
    	printf("%d
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    保罗·多兰《设计幸福》阅读笔记
    依梦随忆(她)
    科技与人性的交汇处----人和机器人的边际在哪里?
    luogu 5月月赛 #A
    luogu P3916 图的遍历
    数论基础之组合数&计数问题
    洛谷——P3173 [HAOI2009]巧克力
    洛谷——P1748 H数
    洛谷——P1404 平均数
    POJ2454——Jersey Politics
  • 原文地址:https://www.cnblogs.com/Mychael/p/9304882.html
Copyright © 2020-2023  润新知