当前位置: 代码迷 >> 综合 >> 并查集 hdu5652 India and China Origins
  详细解决方案

并查集 hdu5652 India and China Origins

热度:86   发布时间:2023-12-14 03:17:48.0

传送门:点击打开链接

题意:告诉你地图的大小,每年有的地方会长出山峰,问什么时候两端开始不连通的。

思路:先到最后一年,就是长出很多山峰时开始。

之后相当于把山峰拆掉,所以就是把4个方向的空地用并查集合并,然后判断两端是否已经连通。

就这样倒着xjb搞,就能出答案了,注意点细节和输出答案的时间就行了

#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <stack>
#include <queue>
#include <cstdio>
#include <cctype>
#include <string>
#include <vector>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
#include <functional>
#define fuck(x) cout<<"["<<x<<"]"
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w+",stdout)
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;const int MX = 4e5 + 5;
const int mod = 1e9 + 7;int P[MX];
int find(int x) {return P[x] == x ? x : (P[x] = find(P[x]));
}int n, m, Q;
char S[505][505];
int WX[MX], WY[MX];
int dist[][2] = {
   {0, 1}, {0, -1}, {1, 0}, { -1, 0}};inline int id(int x, int y) {return (x - 1) * m + y;
}
inline void Union(int u, int v) {u = find(u); v = find(v);if(u != v) P[v] = u;
}int main() {//FIN;int T; scanf("%d", &T);while(T--) {scanf("%d%d", &n, &m);int Begin = m * n + 1, End = m * n + 2, tot = m * n + 2;for(int i = 1; i <= tot; i++) {P[i] = i;}for(int i = 1; i <= n; i++) {scanf("%s", S[i] + 1);}scanf("%d", &Q);for(int i = 1; i <= Q; i++) {scanf("%d%d", &WX[i], &WY[i]);WX[i]++; WY[i]++;S[WX[i]][WY[i]] = '1';}for(int i = 1; i <= n; i++) {for(int j = 1; j <= m; j++) {if(S[i][j] == '0') {for(int k = 0; k < 4; k++) {int nx = i + dist[k][0], ny = j + dist[k][1];if(ny < 1 || ny > m || S[nx][ny] == '1') continue;if(nx == 0) Union(id(i, j), Begin);else if(nx == n + 1) Union(id(i, j), End);else Union(id(i, j), id(nx, ny));}}}}int ans = 0;if(find(Begin) == find(End)) {printf("-1\n");continue;}for(int i = Q; i >= 1; i--) {S[WX[i]][WY[i]] = '0';for(int k = 0; k < 4; k++) {int nx = WX[i] + dist[k][0], ny = WY[i] + dist[k][1];if(ny < 1 || ny > m || S[nx][ny] == '1') continue;if(nx == 0) Union(id(WX[i], WY[i]), Begin);else if(nx == n + 1) Union(id(WX[i], WY[i]), End);else Union(id(WX[i], WY[i]), id(nx, ny));}if(find(Begin) == find(End)) {ans = i; break;}}printf("%d\n", ans);}return 0;
}


  相关解决方案