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

    Source

    Solution

      类比网络流,每一只蜥蜴的路径就是一条$1$的流,柱子高度减小相当于流量上限减小,然后就可以类比着构出网络流的图:

      将每一个柱子拆成两个点,之间连边,流量为这根柱子的高度,借用黄学长的说法,相当于柱子底部到柱子顶部连一条边

      超级源点向所有有蜥蜴的柱子连$1$的边,所有可以跳出地图的柱子向超级汇点连$INF$的边(由于单次最大流不超过$400$所以这里边权我写的$400$)

      如果一根柱子可以到达另一根,就把该柱子的顶连到另一根的底部,边权$INF$(嗯。。。)

      用总蜥蜴数减最大流就是剩下的蜥蜴数

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 struct edge
     4 {
     5     int v, w, nxt;
     6 }e[30005];
     7 int r, c, fst[805], h[25][25], level[805], q[805], etot = 1;
     8 char s[25];
     9 
    10 void addedge(int u, int v, int w)
    11 {
    12     e[++etot] = (edge){v, w, fst[u]}, fst[u] = etot;
    13     e[++etot] = (edge){u, 0, fst[v]}, fst[v] = etot;
    14 }
    15 
    16 int BFS()
    17 {
    18     int front = 0, back, u;
    19     memset(level, 0, sizeof(level));
    20     level[2 * r * c + 1] = 1, q[back = 1] = 2 * r * c + 1;
    21     while(front != back)
    22     {
    23         u = q[++front];
    24         for(int i = fst[u]; i; i = e[i].nxt)
    25             if(e[i].w && !level[e[i].v])
    26             {
    27                 level[e[i].v] = level[u] + 1;
    28                 q[++back] = e[i].v;
    29             }
    30     }
    31     return level[2 * r * c + 2];
    32 }
    33 
    34 int Dinic(int u, int lim)
    35 {
    36     int tmp = lim;
    37     if(u == 2 * r * c + 2) return lim;
    38     for(int i = fst[u]; i; i = e[i].nxt)
    39         if(e[i].w && level[e[i].v] == level[u] + 1)
    40         {
    41             int flow = Dinic(e[i].v, min(tmp, e[i].w));
    42             e[i].w -= flow, e[i ^ 1].w += flow;
    43             if(!(tmp -= flow)) break;
    44         }
    45     if(tmp == lim) level[u] = 0;
    46     return lim - tmp;
    47 }
    48 
    49 int main()
    50 {
    51     int d, ans = 0;
    52     scanf("%d%d%d", &r, &c, &d);
    53     for(int i = 0; i < r; ++i)
    54     {
    55         scanf("%s", s + 1);
    56         for(int j = 1; j <= c; ++j)
    57         {
    58             h[i + 1][j] = s[j] - 48;
    59             addedge(i * c + j, (r + i) * c + j, h[i + 1][j]);
    60         }
    61     }
    62     for(int i = 0; i < r; ++i)
    63     {
    64         scanf("%s", s + 1);
    65         for(int j = 1; j <= c; ++j)
    66             if(s[j] == 'L')
    67                 ++ans, addedge(2 * r * c + 1, i * c + j, 1);
    68     }
    69     for(int i = 0; i < r; ++i)
    70         for(int j = 1; j <= c; ++j)
    71             if(h[i + 1][j] && (i < d || i >= r - d || j <= d || j > c - d))
    72                 addedge((r + i) * c + j, 2 * r * c + 2, 400);
    73     for(int i = d; i < r - d; ++i)
    74         for(int j = d + 1; j <= c - d; ++j)
    75             if(h[i + 1][j])
    76                 for(int k = -d; k <= d; ++k)
    77                     for(int l = -d; l <= d; ++l)
    78                         if(h[i + k + 1][j + l] && k * k + l * l <= d * d)
    79                             addedge((r + i) * c + j, (i + k) * c + j + l, 400);
    80     while(BFS())
    81         ans -= Dinic(2 * r * c + 1, 400);
    82     printf("%d
    ", ans);
    83     return 0;
    84 }
    View Code
  • 相关阅读:
    PHP设计模式
    PHP设计模式
    PHP 23种设计模式
    MySQL 中的共享锁和排他锁的用法
    PHP_MySQL高并发加锁事务处理
    Connection: close和Connection: keep-alive有什么区别
    罗辑思维首席架构师:Go微服务改造实践
    真诚与尊重是技术团队的管理要点
    10种常见的软件架构模式
    百亿级微信红包的高并发资金交易系统设计方案
  • 原文地址:https://www.cnblogs.com/CtrlCV/p/5627852.html
Copyright © 2011-2022 走看看