Description

  在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃
到边界外。 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到平面距离不超过d的任何一个石
柱上。石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减1(如果仍然落在地图内部,则到达的石柱高度不
变),如果该石柱原来高度为1,则蜥蜴离开后消失。以后其他蜥蜴不能落脚。任何时刻不能有两只蜥蜴在同一个
石柱上。

Input

  输入第一行为三个整数r,c,d,即地图的规模与最大跳跃距离。以下r行为石竹的初始状态,0表示没有石柱
,1~3表示石柱的初始高度。以下r行为蜥蜴位置,“L”表示蜥蜴,“.”表示没有蜥蜴。

Output

  输出仅一行,包含一个整数,即无法逃离的蜥蜴总数的最小值。

Sample Input

5 8 2
00000000
02000000
00321100
02000000
00000000
........
........
..LLLL..
........
........

Sample Output

1

HINT

100%的数据满足:1<=r, c<=20, 1<=d<=4

Solution

最大流。

拆点,将一个点拆成两个点,一个点表示进来,另一个点表示出去。进来出去的点的个数不能超过数字个数。然后距离d以内的连一下最后流一下就好了。

Code

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue> #ifdef WIN32
#define LL "%I64d"
#else
#define LL "%lld"
#endif #ifdef CT
#define debug(...) printf(__VA_ARGS__)
#define setfile()
#else
#define debug(...)
#define filename ""
#define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout)
#endif #define R register
#define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
#define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
#define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
#define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
#define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
#define cabs(_x) ((_x) < 0 ? (- (_x)) : (_x))
char B[ << ], *S = B, *T = B;
inline int F()
{
R char ch; R int cnt = ; R bool minus = ;
while (ch = getc(), (ch < '' || ch > '') && ch != '-') ;
ch == '-' ? minus = : cnt = ch - '';
while (ch = getc(), ch >= '' && ch <= '') cnt = cnt * + ch - '';
return minus ? -cnt : cnt;
}
#define maxn 30
#define maxp 10010
#define maxm 1000010
#define inf 0x7fffffff
char mp[maxn][maxn], mp2[maxn][maxn];
int id[maxn][maxn][], id2[maxn][maxn];
struct Edge
{
Edge *next, *rev;
int to, cap;
}*last[maxp], *cur[maxp], e[maxm], *ecnt = e;
int dep[maxp], s, t, ans;
std::queue<int> q;
inline void link(R int a, R int b, R int w)
{
// printf("%d %d %d\n", a, b, w );
*++ecnt = (Edge) {last[a], ecnt + , b, w}; last[a] = ecnt;
*++ecnt = (Edge) {last[b], ecnt - , a, }; last[b] = ecnt;
}
inline bool bfs()
{
memset(dep, -, sizeof (dep));
dep[t] = ; q.push(t);
while (!q.empty())
{
R int now = q.front(); q.pop();
for (R Edge *iter = last[now]; iter; iter = iter -> next)
{
R int pre = iter -> to;
if (dep[pre] == - && iter -> rev -> cap)
{
dep[pre] = dep[now] + ;
q.push(pre);
}
}
}
return dep[s] != -;
}
int dfs(R int x, R int f)
{
if (x == t) return f;
R int used = ;
for (R Edge* &iter = cur[x]; iter; iter = iter -> next)
{
R int pre = iter -> to;
if (iter -> cap && dep[x] == dep[pre] + )
{
R int v = dfs(pre, dmin(iter -> cap, f - used));
iter -> cap -= v;
iter -> rev -> cap += v;
used += v;
if (f == used) return f;
}
}
if (!used) dep[x] = -;
return used;
}
inline void dinic()
{
while (bfs())
{
memcpy(cur, last, sizeof last);
ans += dfs(s, inf);
}
}
int main()
{
// setfile();
R int n = F(), m = F(), k = F(), cnt = , tot = ;
for (R int i = ; i <= n; ++i, getc())
for (R int j = ; j <= m; ++j)
{
mp[i][j] = getc();
if (mp[i][j] > '')
{
id[i][j][] = ++cnt;
id[i][j][] = ++cnt;
link(cnt - , cnt, mp[i][j] - '');
}
}
// for (R int i = 1; i <= n; ++i) puts(mp[i] + 1);
for (R int i = ; i <= n; ++i, getc())
for (R int j = ; j <= m; ++j)
{
mp2[i][j] = getc();
mp2[i][j] == 'L' ? ++tot : ;
}
t = ++cnt;
for (R int i = ; i <= n; ++i)
for (R int j = ; j <= m; ++j)
if (mp[i][j] > '')
{
for (R int ii = -k; ii <= k; ++ii)
for (R int jj = -k; jj <= k; ++jj)
if (i + ii > && i + ii <= n && j + jj > && j + jj <= m && !(ii == && jj == ) && mp[i + ii][j + jj] > '' && ii * ii + jj * jj <= k * k)
link(id[i][j][], id[i + ii][j + jj][], inf);
if (dmin(i, n - i + ) <= k || dmin(j, m - j + ) <= k)
link(id[i][j][], t, inf);
}
for (R int i = ; i <= n; ++i)
for (R int j = ; j <= m; ++j)
if (mp2[i][j] == 'L')
link(s, id[i][j][], );
dinic();
printf("%d\n", tot - ans );
return ;
}
/*
5 8 2
00000000
02000000
00321100
02000000
00000000
........
........
..LLLL..
........
........
*/
05-11 21:48