[BZOJ1066][SCOI2007]蜥蜴[最大流]
每个柱子拆成两个点 连一条柱子高度的边限流
源点->蜥蜴->汇点 或者 源点->蜥蜴->拆成的第一个点->拆成的第二个点->汇点
细节多
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1207;
const int MAXM = 2e5+7;
const int inf = 0x3f3f3f3f-1;
char mat1[24][25], mat2[24][25];
int head[MAXN], dep[MAXN], tot = 1, cur[MAXN], maxflow;
int n, m, a, b, tmp, s, t, d;
struct Edge {
int v, w, next;
} G[MAXM<<1];
inline void add(int u, int v, int w) {
G[++tot] = (Edge) {v, w, head[u]};head[u] = tot;
G[++tot] = (Edge) {u, 0, head[v]};head[v] = tot;
}
bool bfs(int s, int t) {
memset(dep, 0x3f, sizeof dep);
memcpy(cur, head, sizeof head);
queue<int>q;
while(!q.empty()) q.pop();
dep[s] = 0;
q.push(s);
while(!q.empty()) {
int u = q.front();
q.pop();
for(int i = head[u]; i; i = G[i].next) {
int v = G[i].v, w = G[i].w;
if (dep[v] > inf && w) {
dep[v] = dep[u] + 1;
if (v == t) return 1;
q.push(v);
}
}
}
return dep[t] < inf;
}
int dfs(int u, int t, int limit) {
if (u == t || !limit) return limit;
int flow = 0, f;
for(int i = cur[u]; i; i = G[i].next) {
cur[u] = i;
int v = G[i].v, w = G[i].w;
if (dep[v] == dep[u] + 1 && (f = dfs(v, t, min(w, limit)))) {
flow += f;
limit -= f;
G[i].w -= f;
G[i^1].w += f;
if (!limit) break;
}
}
return flow;
}
inline int get(int x, int y) {
return (x-1)*b + y;
}
void dinic(int s, int t) {
while(bfs(s, t)) maxflow += dfs(s, t, inf);
}
inline bool ok(int x, int y, int xx, int yy) {
return ((x-xx)*(x-xx)+(y-yy)*(y-yy)<=(d*d) && mat1[x][y] > '0' && mat1[xx][yy] > '0');
}
int ans;
int Get[105][105];
int main(void) {
scanf("%d%d%d", &a, &b, &d);
n = a*b*2; s = n+1, t = n+2;
for(int i = 1; i <= a; ++i) scanf("%s", mat1[i]+1);
for(int i = 1; i <= a; ++i) scanf("%s", mat2[i]+1);
for(int i = 1; i <= a; ++i)
for(int j = 1; j <= b; ++j) {
if (mat1[i][j] - '0') add(get(i,j), get(i,j) + a*b, mat1[i][j] - '0');
if (mat2[i][j] == 'L') ++ans, add(s, get(i,j), 1);
}
for(int i = 1; i <= a; ++i)
for(int j = 1; j <= b; ++j) {
if (min(a - i + 1, i) <= d || min(b - j + 1, j) <= d) add(get(i,j)+a*b, t, inf);
}
for(int i = 1; i <= a; ++i)
for(int j = 1; j <= b; ++j)
for(int k = 1; k <= a; ++k)
for(int l = 1; l <= b; ++l) {
if (ok(i,j,k,l)) add(get(i,j) + a*b, get(k,l), inf);
}
dinic(s, t);
cout << ans-maxflow << endl;
return 0;
}