zoukankan      html  css  js  c++  java
  • hdu 3329 The Flood (Flood Fill + MFSet)

    Problem - 3329

      用pfs,将淹没时间调整回来,然后用并查集,时间倒序插入点。

    代码如下:

      1 #include <iostream>
      2 #include <algorithm>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <queue>
      6 
      7 using namespace std;
      8 
      9 const int N = 111;
     10 const int dx[4] = { -1, 0, 1, 0};
     11 const int dy[4] = { 0, -1, 0, 1};
     12 bool vis[N][N];
     13 int mat[N][N];
     14 
     15 typedef pair<int, int> PII;
     16 typedef pair<int, PII> PIII;
     17 priority_queue<PIII> pq;
     18 int n, m;
     19 inline bool inmat(int x, int y) { return 0 <= x && x < n && 0 <= y && y < m;}
     20 
     21 void adjust() {
     22     int ht, cx, cy, nx, ny;
     23     while (!pq.empty()) {
     24         PIII tmp = pq.top();
     25         pq.pop();
     26         ht = -tmp.first, cx = tmp.second.first, cy = tmp.second.second;
     27         //cout << ht << ' ' << cx << ' ' << cy << endl;
     28         for (int i = 0; i < 4; i++) {
     29             nx = cx + dx[i], ny = cy + dy[i];
     30             if (!inmat(nx, ny)) continue;
     31             if (vis[nx][ny]) continue;
     32             mat[nx][ny] = max(ht, mat[nx][ny]);
     33             pq.push(PIII(-mat[nx][ny], PII(nx, ny)));
     34             vis[nx][ny] = true;
     35         }
     36     }
     37     //for (int i = 0; i < n; i++) {
     38         //for (int j = 0; j < m; j++) cout << mat[i][j] << ' ';
     39         //cout << endl;
     40     //}
     41 }
     42 
     43 struct MFS {
     44     int fa[N * N];
     45     void init() { for (int i = 0; i < N * N; i++) fa[i] = i;}
     46     int find(int x) { return fa[x] = fa[x] == x ? x : find(fa[x]);}
     47     bool merge(int x, int y) {
     48         int fx = find(x), fy = find(y);
     49         if (fx == fy) return false;
     50         fa[fx] = fy;
     51         return true;
     52     }
     53 } mfs;
     54 
     55 int work() {
     56     int ret = -1;
     57     for (int i = 0; i < n; i++) {
     58         for (int j = 0; j < m; j++) {
     59             pq.push(PIII(mat[i][j], PII(i, j)));
     60             mat[i][j] = -1;
     61         }
     62     }
     63     PIII tmp;
     64     int nid = 0, mg = 0, nx, ny;
     65     bool sp = false;
     66     mfs.init();
     67     while (!pq.empty()) {
     68         int ct = pq.top().first;
     69         while (!pq.empty() && ct == pq.top().first) {
     70             tmp = pq.top();
     71             int h = tmp.first, x = tmp.second.first, y = tmp.second.second;
     72             pq.pop();
     73             mat[x][y] = nid++;
     74             for (int i = 0; i < 4; i++) {
     75                 nx = x + dx[i], ny = y + dy[i];
     76                 if (!inmat(nx, ny)) continue;
     77                 if (mat[nx][ny] == -1) continue;
     78                 mg += mfs.merge(mat[x][y], mat[nx][ny]);
     79             }
     80         }
     81         if (sp) {
     82             if (mg == nid - 1) ret = ct, sp = false;
     83         } else {
     84             if (mg != nid - 1) sp = true;
     85         }
     86     }
     87     return ret;
     88 }
     89 
     90 int main() {
     91     int cas = 1;
     92        while (~scanf("%d%d", &n, &m) && (n || m)) {
     93         while (!pq.empty()) pq.pop();
     94         memset(vis, 0, sizeof(vis));
     95         for (int i = 0; i < n; i++) {
     96             for (int j = 0; j < m; j++) {
     97                 scanf("%d", &mat[i][j]);
     98                 if (i == 0 || i == n - 1 || j == 0 || j == m - 1) {
     99                     pq.push(PIII(-mat[i][j], PII(i, j)));
    100                     vis[i][j] = true;
    101                 }
    102             }
    103         }
    104         //cout << "??" << endl;
    105         adjust();
    106         int ans = work();
    107         if (ans == -1) printf("Case %d: Island never splits.
    ", cas++);
    108         else printf("Case %d: Island splits when ocean rises %d feet.
    ", cas++, ans);
    109     }    
    110     return 0;
    111 }
    View Code

    ——written by Lyon

  • 相关阅读:
    [HNOI2002]彩票
    贼有意思[最长上升公共子序列](SAC大佬测试题)
    空间漫游(SAC大佬的测试)
    计蒜客NOIP模拟赛D2T3 数三角形
    计蒜客NOIP模拟赛D2T2 直线的交点
    计蒜客NOIP模拟赛(3)D2T1 小区划分
    计蒜客NOIP模拟赛(3)D1T3 任性的国王
    UpdateAfterEvent
    长链剖分学习笔记
    P4292 [WC2010]重建计划
  • 原文地址:https://www.cnblogs.com/LyonLys/p/hdu_3329_Lyon.html
Copyright © 2011-2022 走看看