HDU 5652 India and China Origins(并查集)
来源:互联网 发布:手机淘宝怎么玩 编辑:程序博客网 时间:2024/06/11 13:48
题意:
中国和印度之间有一片地方,把这片地方抽象化,于是就可以看成一个N * M矩阵,其中黑色的代表高山不能
走过去,白色的代表平原,可以通行,人每次可以选择往上下左右四个方向移动,但是随着时间的变化某些白色的平原
会变成黑色的高山,从而变为不可通行,题目中给出一个代表地势的图,然后有 Q 次操作,第 i 次操作 代表在第 i 年
(x, y)处的平原变成了高山,即白色变为了黑色。问中国印度最早彻底断绝的时间,如果在 Q 年后还没有断绝就输出 -1;
思路:
刚开始做的时候一看到图求图的连通性,很自然的用回溯了,这道题用 二分 + 回溯, 二分 + BFS都能做出来,
但是后面觉得还是并查集好理解点,就用并查集又写了一遍,用并查集的思想是如果上下彻底断绝联系,那么说明从
左到右存在一片区域,或者一条线,都是由黑色的方格组成,我们可以在为最左边开辟一个新的节点,最右边也开辟
一个新的节点,如果这俩个节点某一时刻在一个集合里面了那么说明就已经彻底断绝了。
我的方法是:题目中给的图下标是(0 -- N - 1, 0 - -M - 1),我在这里用 (1 -- N,1 -- M )来保存这个图,把第 0 列
和第M + 1都初始化为1,代表最右边最左边刚开始就是不能走的,为最左边开辟一个节点为 0 ,为最右边开辟一个节点
为N * M +1,图中下标为(i, j)的节点以编号 (i - 1) * M + j 代表,也就是图中的点编号从左到右,从上到下分别为1,
2,3,4,5,6.......N * M,如果(i, j)周围八个方向有一个节点的值为 1 那么就可以把这俩个节点并到一个集合里面,在并
的同时查询 0 号节点和 N * M +1号节点是否在一个集合里面,那就说明左右被黑色的联通,上下被彻底断绝联系。
代码:
<pre name="code" class="cpp">#include <stdio.h> #include <string.h> #include <iostream> using namespace std; const int MAXN = 500; int pre[MAXN * MAXN + 7]; int Gra[MAXN + 7][MAXN + 7]; //上下左右以及斜着的八个方向int dirX[] = {-1, -1, -1, 0, 0, 1, 1, 1}; int dirY[] = {-1, 0, 1, -1, 1, -1, 0, 1}; int n, m; //初始化并查集数组void initPre() { for(int i = 0; i <= n * m + 1; i++) pre[i] = i; } //初始化存放图的数组void initGra() { memset(Gra, -1, sizeof(Gra)); for(int i = 1; i <= n; i++)//×î×ó±ßºÍ×îÓÒ±ßÒ»¿ªÊ¼¾ÍÊDz»Á¬Í¨µÄ Gra[i][0] = Gra[i][m + 1] = 1; } //带压缩路径的查找操作int Find(int x) { return x == pre[x] ? x : pre[x] = Find(pre[x]); } void mix(int x, int y) { int fx = Find(x); int fy = Find(y); if(fx > fy) pre[fx] = fy; if(fx < fy) pre[fy] = fx; } //把(i,j)点和其八个方向的不能走的地方并到一个集合里面void deal(int i, int j) { for(int s = 0; s < 8; s++) { int x = i + dirX[s]; int y = j + dirY[s]; if(Gra[x][y] == 1) { if(y == 0) mix(0, (i - 1) * m + j);//最左边 else if(y == m + 1) mix(n * m + 1, (i - 1) * m + j);//最右边 else mix((x - 1) * m + y, (i - 1) * m + j); } } } int main() { //freopen("in.txt", "r", stdin); int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n, &m); initPre(); initGra(); for(int i = 1; i <= n; i++ ){ for(int j = 1; j <= m; j++) { scanf("%1d",&Gra[i][j]); if(Gra[i][j] == 1) deal(i , j); } } int Q; scanf("%d",&Q); int flag = 0;//是否彻底断绝 int ans = -1; if(Find(0) == Find(n * m + 1)){ans = 0; flag = 1; } for(int i = 1; i <= Q; i++) { int x, y; scanf("%d%d",&x, &y); Gra[x + 1][y + 1] = 1; deal(x + 1, y + 1); if( !flag && Find(0) == Find(n * m + 1)){//如果代表最左边的节点和代表最右边的节点在一个集合里面,说明左右联通了,上下断绝了 ans = i; flag = 1; } } printf("%d\n",ans); } return 0; }
- HDU 5652 India and China Origins(并查集)
- HDU-5652 India and China Origins(并查集)
- hdu 5652 India and China Origins (并查集)
- HDU-5652 India and China Origins(并查集)
- HDU 5652 India and China Origins(并查集)
- hdu 5652 India and China Origins 并查集
- hdu 5652 India and China Origins 并查集+BFS
- 【HDOJ 5652】 India and China Origins(并查集)
- 7_4_D题 India and China Origins题解 [hdu 5652](并查集)
- HDU 5652 India and China Origins (并查集判断联通)
- hdu5652 India and China Origins(并查集)
- 并查集 hdu5652 India and China Origins
- hdu5652 India and China Origins(并查集)
- hdu5652 India and China Origins(并查集联通)
- hdu5652 India and China Origins(并查集)
- hdu 5652 India and China Origins(二分)
- hdu 5652 India and China Origins (★)
- hdu 5652 India and China Origins
- Google Java编程风格指南
- CodeForces - 659B Qualifying Contest (模拟)水
- sqlserver中drop、truncate和delete语句的用法
- c#逐行分元素读取记事本txt数据写进数据库
- 包装类怎么参与运算的
- HDU 5652 India and China Origins(并查集)
- 使用Spring 整合 Quartz
- C# 读取EXCEL文件的三种经典方法
- 8种基本数据类型和运算(隐式转换和强制转换)
- swift可选类型
- 入手友善之臂Cortex-A9 Tiny4412 开发板
- LayoutTransition(布局容器动画)
- 2016中山市邀请赛
- 711 无法加载远程访问连接管理服务 Remote Access connection Manager 126 找不到指定的模块