zoukankan      html  css  js  c++  java
  • bzoj 1066 [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


      比较基础(水),按照题目大意,能跳的地方连边,每个点(除了源点和汇点)拆成两个点,中间连一条容量为这个石柱的高度(设置节点容量),有蜥蜴的地方源点向它连边,能够跳出地图的点就向汇点连边。这个网络的最大流表示最大能够逃生的蜥蜴数量,用蜥蜴数量一减就是答案。

    Code

      1 /**
      2  * bzoj
      3  * Problem#1066
      4  * Accepted
      5  * Time:40ms
      6  * Memory:1688k
      7  */
      8 #include <iostream>
      9 #include <cstdio>
     10 #include <ctime>
     11 #include <cctype>
     12 #include <cstring>
     13 #include <cstdlib>
     14 #include <fstream>
     15 #include <sstream>
     16 #include <algorithm>
     17 #include <map>
     18 #include <set>
     19 #include <stack>
     20 #include <queue>
     21 #include <vector>
     22 #include <stack>
     23 using namespace std;
     24 typedef bool boolean;
     25 #define inf 0xfffffff
     26 #define smin(a, b) a = min(a, b)
     27 #define smax(a, b) a = max(a, b)
     28 #define max3(a, b, c) max(a, max(b, c))
     29 #define min3(a, b, c) min(a, min(b, c))
     30 template<typename T>
     31 inline boolean readInteger(T& u){
     32     char x;
     33     int aFlag = 1;
     34     while(!isdigit((x = getchar())) && x != '-' && x != -1);
     35     if(x == -1) {
     36         ungetc(x, stdin);
     37         return false;
     38     }
     39     if(x == '-'){
     40         x = getchar();
     41         aFlag = -1;
     42     }
     43     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
     44     ungetc(x, stdin);
     45     u *= aFlag;
     46     return true;
     47 }
     48 
     49 template<typename T>class Matrix{
     50     public:
     51         T *p;
     52         int lines;
     53         int rows;
     54         Matrix():p(NULL){    }
     55         Matrix(int rows, int lines):lines(lines), rows(rows){
     56             p = new T[(lines * rows)];
     57         }
     58         T* operator [](int pos){
     59             return (p + pos * lines);
     60         }
     61 };
     62 #define matset(m, i, s) memset((m).p, (i), (s) * (m).lines * (m).rows)
     63 
     64 typedef class Edge {
     65     public:
     66         int end;
     67         int next;
     68         int flow;
     69         int cap;
     70         Edge(int end = 0, int next = -1, int flow = 0, int cap = 0):end(end), next(next), flow(flow), cap(cap) {    }
     71 }Edge;
     72 
     73 typedef class MapManager {
     74     public:
     75         int ce;
     76         vector<Edge> edge;
     77         int* h;
     78         
     79         MapManager():ce(0), h(NULL) {        }
     80         MapManager(int nodes):ce(0) {
     81             h = new int[(const int)(nodes + 1)];
     82             memset(h, -1, sizeof(int) * (nodes + 1));
     83         }
     84         
     85         inline void addEdge(int from, int end, int flow, int cap) {
     86             edge.push_back(Edge(end, h[from], flow, cap));
     87             h[from] = ce++;
     88         }
     89         
     90         inline void addDoubleEdge(int from, int end, int cap) {
     91             if(cap == 0)    return;
     92 //            cout << from << "->" << end << "(with the cap " << cap << ")" << endl;  
     93             addEdge(from, end, 0, cap);
     94             addEdge(end, from, cap, cap);
     95         }
     96         
     97         Edge& operator [] (int pos) {
     98             return edge[pos];
     99         }
    100 }MapManager;
    101 #define m_begin(g, i) (g).h[(i)]
    102 #define m_endpos -1
    103 
    104 typedef class Point {
    105     public:
    106         int x;
    107         int y;
    108         Point(int x = 0, int y = 0):x(x), y(y) {        }
    109 }Point;
    110 
    111 int n, m, r;
    112 Matrix<char> mmap;
    113 Matrix<char> xiyi;
    114 MapManager g;
    115 int counter = 0;
    116 
    117 int s, t;
    118 int halfsize;
    119 
    120 inline int pos(int x, int y) {    return x * m + y + 1;     }
    121 
    122 inline void init() {
    123     readInteger(n);
    124     readInteger(m);
    125     readInteger(r);
    126     mmap = Matrix<char>(n + 1, m + 1);
    127     xiyi = Matrix<char>(n + 1, m + 1);
    128     getchar();
    129     for(int i = 0; i < n; i++) {
    130         gets(mmap[i]);
    131         for(int j = 0; j < m; j++) {
    132             mmap[i][j] -= '0';
    133         }
    134     }
    135     for(int i = 0; i < n; i++)
    136         gets(xiyi[i]);
    137 }
    138 
    139 const int mov[2][4] = {{1, 0, -1, 0}, {0, 1, 0, -1}};
    140 
    141 Matrix<boolean> vis;
    142 queue<Point> Q;
    143 inline void find(Point s) {
    144     matset(vis, false, sizeof(boolean));
    145     vis[s.x][s.y] = true;
    146     Q.push(s);
    147     while(!Q.empty()) {
    148         Point e = Q.front();
    149         Q.pop();
    150         for(int i = 0; i < 4; i++) {
    151             Point eu(e.x + mov[0][i], e.y + mov[1][i]);
    152             if(abs(eu.x - s.x) + abs(eu.y - s.y) > r)    continue;
    153             if(eu.x < 0 || eu.x >= n)    continue;
    154             if(eu.y < 0 || eu.y >= m)    continue;
    155             if(vis[eu.x][eu.y])        continue;
    156             Q.push(eu);
    157             vis[eu.x][eu.y] = true;
    158             if(mmap[eu.x][eu.y])
    159                 g.addDoubleEdge(pos(s.x, s.y) + halfsize, pos(eu.x, eu.y), inf);
    160         }
    161     }
    162 }
    163 
    164 inline void init_map() {
    165     s = 0, t = n * m + 1;
    166     halfsize = n * m + 1;
    167     g = MapManager(t * 2);
    168     vis = Matrix<boolean>(n + 1, m + 1);
    169     for(int i = 0; i < n; i++) {
    170         for(int j = 0; j < m; j++) {
    171             if((i < r || i >= n - r || j < r || j >= m - r) && mmap[i][j]) g.addDoubleEdge(pos(i, j) + halfsize, t, inf);
    172             if(mmap[i][j])
    173                 find(Point(i, j));
    174             if(xiyi[i][j] == 'L')
    175                 g.addDoubleEdge(s, pos(i, j), 1), counter++;
    176         }
    177     }
    178     for(int i = 0; i < n; i++) {
    179         for(int j = 0; j < m; j++) {
    180             g.addDoubleEdge(pos(i, j), pos(i, j) + halfsize, mmap[i][j]);    
    181         }
    182     }
    183 }
    184 
    185 int* dis;
    186 boolean* vis1;
    187 queue<int> que;
    188 inline boolean bfs() {
    189     memset(vis1, false, sizeof(boolean) * (2 * t + 3));
    190     que.push(s);
    191     vis1[s] = true;
    192     dis[s] = 0;
    193     while(!que.empty()) {
    194         int e = que.front();
    195         que.pop();
    196         for(int i = m_begin(g, e); i != m_endpos; i = g[i].next) {
    197             if(g[i].cap == g[i].flow)    continue;
    198             int eu = g[i].end;
    199             if(vis1[eu])    continue;
    200             vis1[eu] = true;
    201             dis[eu] = dis[e] + 1;
    202             que.push(eu);
    203         }
    204     }
    205     return vis1[t];
    206 }
    207 
    208 int *cur;
    209 inline int blockedflow(int node, int minf) {
    210     if((node == t) || (minf == 0))    return minf;
    211     int f, flow = 0;
    212     for(int& i = cur[node]; i != m_endpos; i = g[i].next) {
    213         int& eu = g[i].end;
    214         if(dis[eu] == dis[node] + 1 && g[i].flow < g[i].cap && (f = blockedflow(eu, min(minf, g[i].cap - g[i].flow))) > 0) {
    215             minf -= f;
    216             flow += f;
    217             g[i].flow += f;
    218             g[i ^ 1].flow -= f;
    219             if(minf == 0)    return flow;
    220         }
    221     }
    222     return flow;
    223 }
    224 
    225 inline void init_dinic() {
    226     vis1 = new boolean[(const int)(2 * t + 3)];
    227     dis = new int[(const int)(2 * t + 3)];
    228     cur = new int[(const int)(2 * t + 3)];
    229 }
    230 
    231 inline int dinic() {
    232     int maxflow = 0;
    233     while(bfs()) {
    234         for(int i = 0; i <= (halfsize << 1); i++)
    235             cur[i] = m_begin(g, i);
    236         maxflow += blockedflow(s, inf);
    237     }
    238     return maxflow;
    239 }
    240 
    241 inline void solve() {
    242     printf("%d
    ", counter - dinic());
    243 }
    244 
    245 int main() {
    246     init();
    247     init_map();
    248     init_dinic();
    249     solve();
    250     return 0;
    251 }
  • 相关阅读:
    Json2JsonArray JsonArray2StringArray
    循环结构
    类型转换代码
    字符串的截取拼接
    循环语句,选择结构的相关代码
    Java代码2-运算符简单运用
    Java代码1
    集合框架
    接口
    继承多态
  • 原文地址:https://www.cnblogs.com/yyf0309/p/7101332.html
Copyright © 2011-2022 走看看