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.\n", cas++);
108         else printf("Case %d: Island splits when ocean rises %d feet.\n", cas++, ans);
109     }    
110     return 0;
111 }
View Code

 

——written by Lyon

转载于:https://www.cnblogs.com/LyonLys/p/hdu_3329_Lyon.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值