用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 }
——written by Lyon