• 蜥蜴 BZOJ 1066


    蜥蜴

    【问题描述】

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

    【输入格式】

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

    【输出格式】

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

    【样例输入】

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

    【样例输出】

    1

    【数据范围】

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


    题解:

    题目中石柱的高度其实就是限制了点的通过次数

    那么把每一个点拆成两个点,分别是进入点和离开点

    每个进入点向对应的离开点连一条容量为石柱高度的边

    每个离开点向能跳到的进入点连一条容量为无限的边

    源点向每个有蜥蜴的进入点连一条容量为1的边

    每个能跳出边界的离开点向汇点连一条容量为无限的边

    跑一遍最大流

      1 #include<algorithm>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<cstdlib>
      5 #include<cstdio>
      6 #include<cmath>
      7 using namespace std;
      8 inline int Get()
      9 {
     10     int x;
     11     char c;
     12     while((c = getchar()) < '0' || c > '9');
     13     x = c - '0';
     14     while((c = getchar()) >= '0' && c <= '9') x = x * 10 + c - '0';
     15     return x;
     16 }
     17 const int inf = 2147483647;
     18 const int me = 100233;
     19 int r, c, d, n;
     20 int num;
     21 int S, T;
     22 struct shape
     23 {
     24     int x, y;
     25 };
     26 shape pos[me];
     27 int point[1001][1001];
     28 int tot = 1, nex[me], fir[me], to[me], val[me];
     29 inline void Add(const int &x, const int &y, const int &z)
     30 {
     31     nex[++tot] = fir[x];
     32     fir[x] = tot;
     33     to[tot] = y;
     34     val[tot] = z;
     35 }
     36 inline void Ins(const int &x, const int &y, const int &z)
     37 {
     38     Add(x, y, z);
     39     Add(y, x, 0);
     40 }
     41 inline int Min(const int &x, const int &y)
     42 {
     43     return (x < y) ? x : y; 
     44 }
     45 inline int Sqr(const int &x)
     46 {
     47     return x * x;
     48 }
     49 int dep[me], que[me];
     50 inline bool Bfs()
     51 {
     52     int t = 0, w = 0;
     53     memset(dep, -1, sizeof(dep));
     54     que[++w] = S;
     55     dep[S] = 1;
     56     while(t < w)
     57     {
     58         int u = que[++t];
     59         for(int i = fir[u]; i; i = nex[i])
     60         {
     61             int v = to[i];
     62             if(dep[v] == -1 && val[i])
     63             {
     64                 dep[v] = dep[u] + 1;
     65                 que[++w] = v;
     66                 if(v == T) return true;
     67             }
     68         }
     69     }
     70     return false;
     71 }
     72 int Dinic(const int &u, const int &flow)
     73 {
     74     if(u == T || !flow) return flow;
     75     int wa = 0;
     76     for(int i = fir[u]; i; i = nex[i])
     77     {
     78         int v = to[i];
     79         if(dep[v] == dep[u] + 1 && val[i])
     80         {
     81             int go = Dinic(v, Min(flow - wa, val[i]));
     82             if(go)
     83             {
     84                 val[i] -= go;
     85                 val[i ^ 1] += go;
     86                 wa += go;
     87                 if(wa == flow) break;
     88             }
     89         }
     90     }
     91     return wa;
     92 }
     93 char s[me];
     94 int main()
     95 {
     96     r = Get(), c = Get(), d = Get();
     97     n = r * c;
     98     S = 0, T = n << 1 | 1;
     99     for(int i = 1; i <= r; ++i)
    100     {
    101         scanf("%s", s);
    102         for(int j = 1; j <= c; ++j)
    103         {
    104             int sa = s[j - 1] - '0';
    105             if(sa)
    106             {
    107                 point[i][j] = ++num;
    108                 pos[num] = (shape) {i, j};
    109                 Ins(num, num + n, sa);
    110                 int dis = Min(i, Min(j, Min(r - i + 1, c - j + 1)));
    111                 if(dis <= d) Ins(num + n, T, inf);
    112                 for(int k = 1; k < num; ++k)
    113                 {
    114                     int x = pos[k].x, y = pos[k].y;
    115                     double dist = sqrt(Sqr(x - i) + Sqr(y - j));
    116                     if(dist <= d)
    117                     {
    118                         Ins(point[x][y] + n, num, inf);
    119                         Ins(num + n, point[x][y], inf);
    120                     }
    121                 }
    122             }
    123         }
    124     }
    125     int ans = 0;
    126     for(int i = 1; i <= r; ++i)
    127     {
    128         scanf("%s", s);
    129         for(int j = 1; j <= c; ++j)
    130             if(s[j - 1] == 'L')
    131             {
    132                 ++ans;
    133                 Ins(S, point[i][j], 1);
    134             }
    135     }
    136     while(Bfs()) ans -= Dinic(S, inf);
    137     printf("%d", ans);
    138 }
  • 相关阅读:
    [SUCTF 2019]Game
    [RoarCTF2019]黄金6年
    espcms代码审计第一弹
    初识搜索
    安恒2018年三月月赛MISC蜘蛛侠呀
    [De1CTF 2019]SSRF Me
    网鼎杯 fakebook
    [0CTF 2016]piapiapia
    [RoarCTF 2019]Easy Java
    [CISCN2019 华北赛区 Day1 Web1]Dropbox
  • 原文地址:https://www.cnblogs.com/lytccc/p/6492568.html
Copyright © 2020-2023  润新知