标签:
【HDOJ 5652】 India and China Origins(并查集)
1 4 6 011010 000010 100001 001000 7 0 3 1 5 1 3 0 0 1 2 2 4 2 1
4
题目大意:许多多年前,中国和印第安是相连接的……恕我地理不好……。。
之间有一些山 其余为平原
地图以1 0表示
1为山脉 0为平原
中国在最上方(横坐标为0
中国在最下方(横坐标为n-1
每个点可以向上下左右四个方向走
有q年地壳运动,每年会增加一座山(以坐标表示<x,y>)
问中国与印第安最早断开连接的年代
思路是离线处理。
存下每年地壳活动的坐标。
从第一年到最后一年把所有出现的山脉在地图上标记出。然后把能相到达的平原合并
然后从最后一年到第一年开始"拆山" 然后找到第一次两国可以相同的时间
这个时间+1就是第一次断开的年代
那么最后一个问题就是求两国此时此刻是否连通。
我的做法是枚举行为n-1(印第安)的所有平原 跑并查集看是否缩到某个行为0(中国)的点上
只要在缩点的时候缩到下标小的点上就行。
注意进行压缩的时候每次压缩玩要重新Find.否则原本的根一定是新根 会出错(在这里卡了老久……
代码如下:
#include <iostream> #include <cmath> #include <vector> #include <cstdlib> #include <cstdio> #include <cstring> #include <queue> #include <stack> #include <list> #include <algorithm> #include <map> #include <set> #define LL long long #define Pr pair<int,int> #define fread() freopen("in.in","r",stdin) #define fwrite() freopen("out.out","w",stdout) using namespace std; const int INF = 0x3f3f3f3f; const int msz = 10000; const int mod = 1e9+7; const double eps = 1e-8; Pr pr[266666]; int pre[266666]; int dirx[] = { 0, 0,-1, 1}; int diry[] = { 1,-1, 0, 0}; char mp[555][555]; int tp; void init(int n) { for(int i = 0; i <= n; ++i) pre[i] = i; } int Find(int x) { return pre[x] == x? pre[x]: (pre[x] = Find(pre[x])); } int n,m; bool cal() { for(int i = 0; i < m; ++i) { //printf("%d:%d %d:%d\n",i,Find(i),j,Find((n-1)*m+j)); if(Find((n-1)*m+i) < m) return 1; } return 0; } int main() { //fread(); //fwrite(); int t; int q,k,r; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(int i = 0; i < n; ++i) scanf("%s",mp[i]); init((n-1)*m+m-1); scanf("%d",&q); for(int i = 0; i < q; ++i) { scanf("%d%d",&pr[i].first,&pr[i].second); mp[pr[i].first][pr[i].second]++; } // for(int i = 0; i < n; ++i) // for(int j = 0; j < m; ++j) // { // printf("pre[%d](%d,%d):%d\n",i*m+j,i,j,pre[i*m+j]); // } for(int i = 0; i < n; ++i) for(int j = 0; j < m; ++j) { if(mp[i][j] != '0') continue; k = Find(i*m+j); if(j+1 < m && mp[i][j+1] == '0') { r = Find(i*m+j+1); if(k < r) pre[r] = k; else pre[k] = r; } k = Find(i*m+j); if(i+1 < n && mp[i+1][j] == '0') { r = Find((i+1)*m+j); if(k < r) pre[r] = k; else pre[k] = r; } } int id = -2; // for(int i = 0; i < n; ++i) // puts(mp[i]); // for(int i = 0; i < n; ++i) // for(int j = 0; j < m; ++j) // { // printf("pre[%d](%d,%d):%d\n",i*m+j,i,j,pre[i*m+j]); // } if(cal()) id = -1; int x,y,xx,yy; for(int i = q-1; i >= 0 && id == -2; --i) { x = pr[i].first; y = pr[i].second; mp[x][y]--; if(mp[x][y] == '0') { k = Find(x*m+y); for(int j = 0; j < 4; ++j) { xx = x+dirx[j]; yy = y+diry[j]; if(0 <= xx && xx < n && 0 <= yy && yy < m && mp[xx][yy] == '0') { r = Find(xx*m+yy); if(k < r) pre[r] = k; else pre[k] = r; k = Find(x*m+y); } } if(cal()) id = i+1; } } printf("%d\n",id == -2? 0: id); } return 0; }
【HDOJ 5652】 India and China Origins(并查集)
标签:
原文地址:http://blog.csdn.net/challengerrumble/article/details/51000789