hdu5652 India and China Origins(并查集)
India and China Origins
Accepts: 49
Submissions: 426
Time Limit: 2000/2000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
问题描述
很久以前,中国和印度之间并没有喜马拉雅山相隔,两国的文化交流很频繁。随着喜马拉雅山海拔逐渐增加,两个地区的交流也越来越少,最终没有了来往。
假设当时的地形和我画的一样,蓝色部分代表海洋,而且当时人们还没有发明轮船。黄色部分代表沙漠,而且沙漠上经常有野鬼散步,所以人们不敢到沙漠中行走。黑色的格子表示山峰,这些山峰都无比高大,所以人无法穿过。白色格子代表平原,人可以在平原上自由行走。人每次可以向相邻的四个格子走动。 此外,我们的考古学家发现还有一些山峰会逐渐形成,通过研究发现,位置在 (x,y) (保证该位置之前没有山峰)的地方在 i 年后出现了山峰。现在给你若干个位置出现山峰的时间,你可以计算出中国和印度之间的联系最早被彻底切断的时间吗?
输入描述
多组测试数据, 第一行为组数T(T≤10)。每组测试数据第一行包含两个数 N,M(1≤N,M≤500), 表示地图的大小。接下来 N 行长度为 M 的 01 字符串。0代表白色格子,1 代表山峰。接下来有 Q(1≤Q≤N×M) 行,第 i(1≤i≤Q) 两个整数 (x,y),0≤x<N,0≤y<M 表示在第 i 年 (x,y) 出现了一座山峰。
输出描述
对于每组测试数据,输出一个数, 表示两国最早失联的时间。如果最终两国之间还有联系则输出 -1。
输入样例
1 4 6 011010 000010 100001 001000 7 0 3 1 5 1 3 0 0 1 2 2 4 2 1
输出样例
4
Hint
从上图可以看到,两国在第四年彻底失去了联系。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | /* hdu5652 India and China Origins(并查集) 给你一个棋盘形状的东东,上面1代表无法越过的山峰,0代表可以通过的平原. 而且在接下来q次会出现一些山峰,问多少次后棋盘上下不连通 如果一直联通则输出-1 开始想到了并查集但是实现起来有点问题,每次插入后都要把最左边一列判断 一下,看他们的父亲是否是棋盘的最右端.感觉并不够简便 然后参考了下大神们的代码,发现可以在合并的时候记录下这个联通量最左边 和最右边的位置,这样每次合并时只需要判断max-min是否等于棋盘的宽度就 好了 果然自己太死板了TAT hhh-2016-03-27 12:42:45 */ #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<functional> using namespace std; #define lson (i<<1) #define rson ((i<<1)|1) typedef long long ll; const int maxn = 505 ; int from = 500*500; int to = 500*500+1; int n,m; int dir[9][2] = {{1,1},{1,0},{0,1},{1,-1},{0,-1},{-1,1},{-1,-1},{-1,0}}; char str[maxn]; int far[maxn*maxn]; int tmap[maxn][maxn]; int l[maxn*maxn],r[maxn*maxn]; int fin( int x) { return x == far[x]? x : far[x] = fin(far[x]); } bool unio( int a, int b) { int ta = fin(a); int tb = fin(b); if (ta != tb) { far[ta] = tb; l[tb] = min(l[ta],l[tb]); r[tb] = max(r[ta],r[tb]); if (r[tb] - l[tb] == m-1) return 1; } return 0; } int main() { int T; scanf ( "%d" ,&T); while (T--) { scanf ( "%d%d" ,&n,&m); for ( int i = 0; i < n; i++) { scanf ( "%s" ,str); for ( int j = 0; j < m; j++) { tmap[i][j] = str[j]- '0' ; far[i*m+j] = i*m+j; } } for ( int i = 0; i < n; i++) { for ( int j = 0; j < m; j++) //if(tmap[i][j]) { l[i*m+j] = j; r[i*m+j] = j; } } int flag =0; for ( int i = 0; i < n; i++) { for ( int j = 0; j < m; j++) { if (tmap[i][j]) { for ( int k = 0; k < 8; k++) { int tx = i + dir[k][0]; int ty = j + dir[k][1]; if (tx < 0 || tx >= n || ty < 0 || ty >= m || !tmap[tx][ty]) continue ; if (unio(i*m+j,tx*m+ty)) flag = 1; } } } } if (flag) printf ( "0\n" ); int q; scanf ( "%d" ,&q); for ( int i = 0; i < q; i++) { int x,y; scanf ( "%d%d" ,&x,&y); tmap[x][y] = 1; if (flag) continue ; for ( int k = 0; k < 8; k++) { int tx = x + dir[k][0]; int ty = y + dir[k][1]; if (tx < 0 || tx >= n || ty < 0 || ty >= m || !tmap[tx][ty]) continue ; if (unio(x*m+y,tx*m+ty)) { flag = 1; printf ( "%d\n" ,i+1); } } } if (!flag) printf ( "-1\n" ); } return 0 ; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步