zoukankan      html  css  js  c++  java
  • bzoj1189: [HNOI2007]紧急疏散evacuate

    看到黄学长的做法觉得有点疑问

    网上搜了下发现确实有问题

    看到PoPoQQQ大爷的啦 http://blog.csdn.net/popoqqq/article/details/41594921

    然后怎么办呢

    得把每个出口拆成很多个时刻 每个时刻到t建边

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<algorithm>
      5 #include<iostream>
      6 
      7 using namespace std;
      8 
      9 void setIO(const string& s) {
     10     freopen((s + ".in").c_str(), "r", stdin);
     11     freopen((s + ".out").c_str(), "w", stdout);
     12 }
     13 template<typename Q> Q read(Q& x) {
     14     static char c, f;
     15     for(f = 0; c = getchar(), !isdigit(c); ) if(c == '-') f = 1;
     16     for(x = 0; isdigit(c); c = getchar()) x = x * 10 + c - '0';
     17     if(f) x = -x;
     18     return x;
     19 }
     20 template<typename Q> Q read() {
     21     static Q x; read(x); return x;
     22 }
     23 
     24 // ISAP
     25 const int N = 40000 + 10, M = 500000 + 10, INF = ~0u >> 1;
     26 const int R = 400;
     27 
     28 struct Edge {
     29     int to, cap, adv;
     30     Edge *next;
     31     void init() {adv = cap;}
     32     Edge(int to = 0, int cap = 0, Edge *next = 0) : to(to), cap(cap), next(next) {}
     33 }pool[M * 2], *pis = pool, *fir[N], *pre[N];
     34 
     35 void AddEdge(int u, int v, int w) {
     36     fir[u] = new(pis++) Edge(v, w, fir[u]);
     37     fir[v] = new(pis++) Edge(u, 0, fir[v]);
     38 }
     39 
     40 Edge *inv(Edge *p) {
     41     return pool + ((p - pool) ^ 1);
     42 }
     43 
     44 namespace ISAP {
     45     int d[N], q[N], ql, qr;
     46     int n, s, t;
     47     int num[N];
     48     Edge *cur[N];
     49     
     50     void insert(int u, int dis) {
     51         if(d[u] == n) {
     52             d[u] = dis;
     53             q[qr++] = u;
     54         }
     55     }
     56     
     57     void BFS() {
     58         for(int u = 1; u <= n; u++) {
     59             d[u] = n;
     60         }
     61         insert(t, 0);
     62         while(ql ^ qr) {
     63             int u = q[ql++];
     64             for(Edge *p = fir[u]; p; p = p->next) if(inv(p)->adv){
     65                 insert(p->to, d[u] + 1);
     66             }
     67         }
     68     }
     69     
     70     int Augment() {
     71         int a = INF;
     72         for(int u = t; u != s; u = inv(pre[u])->to) {
     73             a = min(a, pre[u]->adv);
     74         }
     75         for(int u = t; u != s; u = inv(pre[u])->to) {
     76             pre[u]->adv -= a;
     77             inv(pre[u])->adv += a;
     78         }
     79         return a;
     80     }
     81     
     82     int Maxflow() {
     83         memset(num, 0, sizeof num);
     84         BFS();
     85         for(int u = 1; u <= n; u++) {
     86             cur[u] = fir[u];
     87             num[d[u]]++;
     88         }
     89         for(int i = 1; i < d[s]; i++) {
     90             if(!num[i]) return 0;
     91         }
     92         int flow = 0;
     93         for(int u = s; d[s] < n; ) {
     94             if(u == t) {
     95                 flow += Augment();
     96                 u = s;
     97             }
     98             int ok = 0;
     99             for(Edge *&p = cur[u]; p; p = p->next) if(p->adv) {
    100                 int v = p->to;
    101                 if(d[v] + 1 == d[u]) {
    102                     pre[u = v] = p;
    103                     ok = 1;
    104                     break;
    105                 }
    106             }
    107             if(!ok) {
    108                 int &dis = d[u];
    109                 if(!--num[dis]) break;
    110                 dis = n;
    111                 for(Edge *p = (cur[u] = fir[u]); p; p = p->next) if(p->adv) {
    112                     dis = min(dis, d[p->to] + 1);
    113                 }
    114                 num[dis]++;
    115                 if(u != s) u = inv(pre[u])->to;
    116             }
    117         }
    118         return flow;
    119     }
    120     
    121     int main(int _n, int _s, int _t) {
    122         n = _n, s = _s, t = _t;
    123         return Maxflow();
    124     }
    125 }
    126 
    127 const int maxn = 20 + 5;
    128 
    129 int n, m;
    130 char g[maxn][maxn];
    131 
    132 int encode(int x, int y) {
    133     return (x - 1) * m + y;
    134 }
    135 
    136 void discode(int s, int& x, int& y) {
    137     y = (s - 1) % m + 1;
    138     x = (s - y) / m + 1;
    139 }
    140 
    141 int mid;
    142 
    143 int q[maxn * maxn], ql, qr;
    144 int d[maxn][maxn];
    145 
    146 void insert(int x, int y, int dis) {
    147     if(d[x][y] > dis) {
    148         d[x][y] = dis;
    149         if(g[x][y] != 'D') q[qr++] = encode(x, y);
    150     }
    151 }
    152 
    153 const int dx[] = {0, 0, 1, -1};
    154 const int dy[] = {1, -1, 0, 0};
    155 
    156 bool inmap(int x, int y) {
    157     return 0 < x && x <= n && 0 < y && y <= m;
    158 }
    159 
    160 int tot;
    161 #include<vector>
    162 vector<int> doors;
    163 int ND[R][R];
    164 Edge *rec[R][R];
    165 
    166 void BFS(int sx, int sy) {//(2, 2) -> (n - 1, n - 1)
    167     memset(d, 0x3f, sizeof d);
    168     ql = qr = 0;
    169     insert(sx, sy, 0);
    170     while(ql ^ qr) {
    171         int s = q[ql++], x, y;
    172         discode(s, x, y);
    173         for(int k = 0; k < 4; k++) {
    174             int xx = x + dx[k], yy = y + dy[k];
    175             if(inmap(xx, yy) && g[xx][yy] != 'X') insert(xx, yy, d[x][y] + 1);
    176         }
    177     }
    178 }
    179 
    180 void build(int s, int& cnt) {
    181     for(int x0 = 2; x0 < n; x0++) {
    182         for(int y0 = 2; y0 < m; y0++) if(g[x0][y0] == '.') {
    183             ++cnt;
    184             BFS(x0, y0); int u = encode(x0, y0);
    185             AddEdge(s, u, 1);
    186             for(unsigned i = 0; i < doors.size(); i++) {
    187                 int v = doors[i], x, y; discode(v, x, y);
    188                 if(d[x][y] < R) AddEdge(u, ND[v][d[x][y]], 1);
    189             }
    190         }
    191     }
    192 }
    193 
    194 void rebuild(int mid) {
    195     for(Edge *p = pool; p != pis; (p++)->init());
    196     for(unsigned i = 0; i < doors.size(); i++) {
    197         int u = doors[i];
    198         for(int j = mid + 1; j < R; j++) rec[u][j]->adv = 0;
    199     }
    200 }
    201 
    202 void find_doors(int t) {
    203     for(int i = 1; i <= n; i++) {
    204         for(int j = 1; j <= m; j += m - 1) {
    205             if(g[i][j] == 'D') {
    206                 doors.push_back(encode(i, j));
    207             }
    208         }
    209     }
    210     for(int j = 2; j < m; j++) {
    211         for(int i = 1; i <= n; i += n - 1) {
    212             if(g[i][j] == 'D') {
    213                 doors.push_back(encode(i, j));
    214             }
    215         }
    216     }
    217     tot = n * m;
    218     for(unsigned i = 0; i < doors.size(); i++) {
    219         int u = doors[i];
    220         for(int j = 1; j < R; j++) {
    221             ND[u][j] = ++tot;
    222             AddEdge(tot, t, 1);
    223             rec[u][j] = pis - 2;
    224             if(j > 1) AddEdge(tot - 1, tot, INF);
    225         }
    226     }
    227 }
    228 
    229 int main() {
    230 #ifdef DEBUG
    231     freopen("in.txt", "r", stdin);
    232     freopen("out.txt", "w", stdout);
    233 #endif
    234     
    235     read(n), read(m);
    236     for(int i = 1; i <= n; i++) {
    237         scanf("%s", g[i] + 1);
    238     }
    239     
    240     int s = 40000 + 1, t = 40000 + 2, cnt;
    241     
    242     find_doors(t);
    243     build(s, cnt = 0);
    244     int l = 0, r = R - 1, res = INF;
    245     while(l <= r) {
    246         int mid = (l + r) >> 1;
    247         rebuild(mid);
    248         int tmp = ISAP::main(t, s, t);
    249         if(tmp >= cnt) r = mid - 1, res = mid;
    250         else l = mid + 1;
    251     }
    252     if(res == INF) puts("impossible");
    253     else printf("%d
    ", res);
    254     
    255     return 0;
    256 }
  • 相关阅读:
    OD 实验(十三)
    第一个 Windows 界面程序
    C 语言
    C 语言
    OD 实验(十二)
    PowerShell 常用命令
    OD 实验(十一)
    OD 实验(十)
    redis
    memcached缓存系统
  • 原文地址:https://www.cnblogs.com/showson/p/5037190.html
Copyright © 2011-2022 走看看