BZOJ2150php
複習:
帶上下界網絡流兩種寫法:ios
二者本質同樣,但後者在\(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\n",ans); return 0; }