首先。。。这是道(很水的)网络流

我们发现"每个时刻不能有两个蜥蜴在同一个柱子上"这个条件是没有用的因为可以让外面的先跳,再让里面的往外跳

但是还有柱子高度的限制,于是把柱子拆点为p1和p2,p1向p2连边,边权为柱子高度

对于相距(注意!是欧几里得距离!)小于d的两个柱子p和q,q2向p1连边,p2向q1连边,边权为inf

S向有蜥蜴的柱子的p1连边,边权为1,可以一步跳出去的柱子p2向T连边,边权为inf

跑最大流即可

 

  1 /**************************************************************
  2     Problem: 1066
  3     User: rausen
  4     Language: C++
  5     Result: Accepted
  6     Time:136 ms
  7     Memory:12656 kb
  8 ****************************************************************/
  9  
 10 #include <cstdio>
 11 #include <cstring>
 12 #include <algorithm>
 13  
 14 using namespace std;
 15 const int N = 1e3 + 5;
 16 const int M = N * N;
 17 const int inf = 1e9;
 18  
 19 struct edge {
 20     int next, to, f;
 21     edge(int _n = 0, int _t = 0, int _f = 0) : next(_n), to(_t), f(_f) {}
 22 } e[M];
 23  
 24 int n, m, D, cnt_p, S, T, ans;
 25 int first[N], tot = 1;
 26 int w[25][25];
 27 int d[N], q[N];
 28  
 29 inline void Add_Edges(int x, int y, int f) {
 30     e[++tot] = edge(first[x], y, f), first[x] = tot;
 31     e[++tot] = edge(first[y], x, 0), first[y] = tot;
 32 }
 33   
 34 #define y e[x].to
 35 #define p q[l]
 36 bool bfs() {
 37   static int l, r, x;
 38   memset(d, -1, sizeof(d));
 39   d[q[1] = S] = 1;
 40   for (l = r = 1; l != r + 1; ++l)
 41     for (x = first[p]; x; x = e[x].next)
 42       if (!~d[y] && e[x].f) {
 43     d[q[++r] = y] = d[p] + 1;
 44     if (y == T) return 1;
 45       }
 46   return 0;
 47 }
 48 #undef p
 49   
 50 int dfs(int p, int lim) {
 51   if (p == T || !lim) return lim;
 52   int x, tmp, rest = lim;
 53   for (x = first[p]; x && rest; x = e[x].next) 
 54     if (d[y] == d[p] + 1 && ((tmp = min(e[x].f, rest)) > 0)) {
 55       rest -= (tmp = dfs(y, tmp));
 56       e[x].f -= tmp, e[x ^ 1].f += tmp;
 57       if (!rest) return lim;
 58     }
 59   if (rest) d[p] = -1;
 60   return lim - rest;
 61 }
 62 #undef y
 63   
 64 inline int Dinic() {
 65   int res = 0;
 66   while (bfs())
 67     res += dfs(S, inf);
 68   return res;
 69 }
 70  
 71 template <class T> T sqr(T x) {
 72     return x * x;
 73 }
 74  
 75 #define in(x, y) w[x][y] * 2 - 1
 76 #define out(x, y) w[x][y] * 2
 77 int main() {
 78     int i, j, k, l;
 79     char ch;
 80     scanf("%d%d%d", &n, &m, &D);
 81     for (cnt_p = 0, i = 1; i <= n; ++i)
 82         for (j = 1; j <= m; ++j) {
 83             ch = getchar();
 84             while (ch < '0' || ch > '3') ch = getchar();
 85             w[i][j] = ++cnt_p;
 86             if (ch != '0') Add_Edges(in(i, j), out(i, j), ch - '0');
 87         }
 88     S = cnt_p * 2 + 1, T = S + 1;
 89     for (i = 1; i <= n; ++i)
 90         for (j = 1; j <= m; ++j)
 91             for (k = 1; k <= n; ++k)
 92                 for (l = 1; l <= m; ++l)
 93                     if (sqr(i - k) + sqr(j - l) <= D * D && ((i != k) || (j != l)))
 94                         Add_Edges(out(i, j), in(k, l), inf);
 95     for (i = 1; i <= n; ++i)
 96         for (j = 1; j <= m; ++j) {
 97             ch = getchar();
 98             while (ch != '.' && ch != 'L') ch = getchar();
 99             if (ch == 'L') ++ans, Add_Edges(S, in(i, j), 1);
100             if (i <= D || j <= D || i > n - D || j > m - D)
101                 Add_Edges(out(i, j), T, inf);
102         }
103     printf("%d\n", ans - Dinic());
104     return 0;
105 }
106 #undef in
107 #undef out
View Code

 

posted on 2015-04-11 11:30  Xs酱~  阅读(109)  评论(0编辑  收藏