zoukankan      html  css  js  c++  java
  • 【BZOJ1066】 [SCOI2007]蜥蜴

    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

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #include <cmath>
      5 #include <queue>
      6 
      7 #ifdef WIN32
      8     #define LL "%I64d"
      9 #else
     10     #define LL "%lld"
     11 #endif
     12 
     13 #ifdef CT
     14     #define debug(...) printf(__VA_ARGS__)
     15     #define setfile() 
     16 #else
     17     #define debug(...)
     18     #define filename ""
     19     #define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout)
     20 #endif
     21 
     22 #define R register
     23 #define getc() (S == T && (T = (S = B) + fread(B, 1, 1 << 15, stdin), S == T) ? EOF : *S++)
     24 #define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b))
     25 #define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
     26 #define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0)
     27 #define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
     28 #define cabs(_x) ((_x) < 0 ? (- (_x)) : (_x))
     29 char B[1 << 15], *S = B, *T = B;
     30 inline int F()
     31 {
     32     R char ch; R int cnt = 0; R bool minus = 0;
     33     while (ch = getc(), (ch < '0' || ch > '9') && ch != '-') ;
     34     ch == '-' ? minus = 1 : cnt = ch - '0';
     35     while (ch = getc(), ch >= '0' && ch <= '9') cnt = cnt * 10 + ch - '0';
     36     return minus ? -cnt : cnt;
     37 }
     38 #define maxn 30
     39 #define maxp 10010
     40 #define maxm 1000010
     41 #define inf 0x7fffffff
     42 char mp[maxn][maxn], mp2[maxn][maxn];
     43 int id[maxn][maxn][2], id2[maxn][maxn];
     44 struct Edge
     45 {
     46     Edge *next, *rev;
     47     int to, cap;
     48 }*last[maxp], *cur[maxp], e[maxm], *ecnt = e;
     49 int dep[maxp], s, t, ans;
     50 std::queue<int> q;
     51 inline void link(R int a, R int b, R int w)
     52 {
     53 //    printf("%d %d %d
    ", a, b, w );
     54     *++ecnt = (Edge) {last[a], ecnt + 1, b, w}; last[a] = ecnt;
     55     *++ecnt = (Edge) {last[b], ecnt - 1, a, 0}; last[b] = ecnt;
     56 }
     57 inline bool bfs()
     58 {
     59     memset(dep, -1, sizeof (dep));
     60     dep[t] = 0; q.push(t);
     61     while (!q.empty())
     62     {
     63         R int now = q.front(); q.pop();
     64         for (R Edge *iter = last[now]; iter; iter = iter -> next)
     65         {
     66             R int pre = iter -> to;
     67             if (dep[pre] == -1 && iter -> rev -> cap)
     68             {
     69                 dep[pre] = dep[now] + 1;
     70                 q.push(pre);
     71             }
     72         }
     73     }
     74     return dep[s] != -1;
     75 }
     76 int dfs(R int x, R int f)
     77 {
     78     if (x == t) return f;
     79     R int used = 0;
     80     for (R Edge* &iter = cur[x]; iter; iter = iter -> next)
     81     {
     82         R int pre = iter -> to;
     83         if (iter -> cap && dep[x] == dep[pre] + 1)
     84         {
     85             R int v = dfs(pre, dmin(iter -> cap, f - used));
     86             iter -> cap -= v;
     87             iter -> rev -> cap += v;
     88             used += v;
     89             if (f == used) return f;
     90         }
     91     }
     92     if (!used) dep[x] = -1;
     93     return used;
     94 }
     95 inline void dinic()
     96 {
     97     while (bfs())
     98     {
     99         memcpy(cur, last, sizeof last);
    100         ans += dfs(s, inf);
    101     }
    102 }
    103 int main()
    104 {
    105 //    setfile();
    106     R int n = F(), m = F(), k = F(), cnt = 0, tot = 0;
    107     for (R int i = 1; i <= n; ++i, getc())
    108         for (R int j = 1; j <= m; ++j)
    109         {
    110             mp[i][j] = getc();
    111             if (mp[i][j] > '0')
    112             {
    113                 id[i][j][0] = ++cnt;
    114                 id[i][j][1] = ++cnt;
    115                 link(cnt - 1, cnt, mp[i][j] - '0');
    116             }
    117         }
    118 //    for (R int i = 1; i <= n; ++i) puts(mp[i] + 1);
    119     for (R int i = 1; i <= n; ++i, getc())
    120         for (R int j = 1; j <= m; ++j)
    121         {
    122             mp2[i][j] = getc();
    123             mp2[i][j] == 'L' ? ++tot : 0;
    124         }
    125     t = ++cnt;
    126     for (R int i = 1; i <= n; ++i)
    127         for (R int j = 1; j <= m; ++j)
    128             if (mp[i][j] > '0')
    129             {
    130                 for (R int ii = -k; ii <= k; ++ii)
    131                     for (R int jj = -k; jj <= k; ++jj)
    132                         if (i + ii > 0 && i + ii <= n && j + jj > 0 && j + jj <= m && !(ii == 0 && jj == 0) && mp[i + ii][j + jj] > '0' && ii * ii + jj * jj <= k * k)
    133                             link(id[i][j][1], id[i + ii][j + jj][0], inf);
    134                 if (dmin(i, n - i + 1) <= k || dmin(j, m - j + 1) <= k)
    135                     link(id[i][j][1], t, inf);
    136             }
    137     for (R int i = 1; i <= n; ++i)
    138         for (R int j = 1; j <= m; ++j)
    139             if (mp2[i][j] == 'L')
    140                 link(s, id[i][j][0], 1);
    141     dinic();
    142     printf("%d
    ", tot - ans );
    143     return 0;
    144 }
    145 /*
    146 5 8 2
    147 00000000
    148 02000000
    149 00321100
    150 02000000
    151 00000000
    152 ........
    153 ........
    154 ..LLLL..
    155 ........
    156 ........
    157 */
  • 相关阅读:
    桟错误分析方法
    gstreamer调试命令
    sqlite的事务和锁,很透彻的讲解 【转】
    严重: Exception starting filter struts2 java.lang.NullPointerException (转载)
    eclipse 快捷键
    POJ 1099 Square Ice
    HDU 1013 Digital Roots
    HDU 1087 Super Jumping! Jumping! Jumping!(动态规划)
    HDU 1159 Common Subsequence
    HDU 1069 Monkey and Banana(动态规划)
  • 原文地址:https://www.cnblogs.com/cocottt/p/6622510.html
Copyright © 2011-2022 走看看