特别经典的一个题,还有一种方法就是二分+bfs

题意:空间内n*m个点,每个点是0或者1,0代表此点可以走,1代表不能走。接着经过q年,每年一个坐标表示此点不能走。问哪年开始图上不能出现最上边不能到达最下边的情况了

图上连通性可以使用并查集判断,但是并查集不善于删边,却善于添边。所以我们倒着来想就是离线倒序添边(横向并查,再纵向并查),当某次判断时图已经连通,就结束。

我使用二维并查集,其实就是使用结构体代替一维数组。接着就是每次一定要从x轴小的点到达x轴大的点,最后注意添边时,我们需要此点向四个方向判断添边

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define eps 1E-8
/*注意可能会有输出-0.000*/
#define Sgn(x) (x<-eps? -1 :x<eps? 0:1)//x为两个浮点数差的比较,注意返回整型
#define Cvs(x) (x > 0.0 ? x+eps : x-eps)//浮点数转化
#define zero(x) (((x)>0?(x):-(x))<eps)//判断是否等于0
#define mul(a,b) (a<<b)
#define dir(a,b) (a>>b)
typedef long long ll;
typedef unsigned long long ull;
const int Inf=<<;
const double Pi=acos(-1.0);
const int Mod=1e9+;
const int Max=;
struct node
{
int xx,yy;
} fat[Max][Max]; //二维并查集
int xx1[Max*Max],yy1[Max*Max];
char str[Max][Max];
int dir[][]= {{,},{-,},{,},{,-}}; //四个方向
void Init(int n,int m)
{
for(int i=; i<n; ++i)
{
for(int j=; j<m; ++j)
{
fat[i][j].xx=i;
fat[i][j].yy=j;
}
}
return ;
}
node Find(int x,int y)
{
if(x==fat[x][y].xx&&y==fat[x][y].yy)
return fat[x][y];
return fat[x][y]=Find(fat[x][y].xx,fat[x][y].yy);
}
int Union(int xx1,int yy1,int xx2,int yy2)//合并两个二维并查集
{
//printf("%d %d %d %d\n",xx1,yy1,xx2,yy2);
node xy1=Find(xx1,yy1);
node xy2=Find(xx2,yy2);
if(xy1.xx==xy2.xx&&xy1.yy==xy2.yy)
return ;
if(xy1.xx<xy2.xx)//保证向下就好
fat[xy1.xx][xy1.yy]=xy2;
else
fat[xy2.xx][xy2.yy]=xy1;
return ;
}
int Jud(int n,int m)//判断是否连通
{
for(int i=; i<m; ++i)
{
node xy1=Find(,i);//第一行可以到达的最下方位置
if(xy1.xx==n-)
return ;
}
return ;
}
int Solve(int n,int m,int q)
{
for(int i=; i<n; ++i)
{
for(int j=; j<m-; ++j)
{
if(str[i][j]==''&&str[i][j+]=='')
{
int ans=Union(i,j,i,j+);//横向合并
//printf("%d\n",ans);
}
}
}
for(int j=; j<m; ++j)
{
for(int i=; i<n-; ++i)
{
if(str[i][j]==''&&str[i+][j]=='')
{
int ans=Union(i,j,i+,j);//纵向合并
//printf("ver=%d\n",ans);
}
}
}
if(Jud(n,m))
return -;
int p;
for(int i=q-; i>=; --i)
{
p=;
str[xx1[i]][yy1[i]]='';
while(p<)
{
if(xx1[i]+dir[p][]>=&&xx1[i]+dir[p][]<n&&yy1[i]+dir[p][]>=&&yy1[i]+dir[p][]<m&&str[xx1[i]+dir[p][]][yy1[i]+dir[p][]]=='')//需要连接四个方向可行的地方
Union(xx1[i],yy1[i],xx1[i]+dir[p][],yy1[i]+dir[p][]);
p++;
}
if(Jud(n,m))
return i+;
}
return ;
}
int main()
{
int t,n,m,q;
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&n,&m);
Init(n,m);
for(int i=; i<n; ++i)
scanf("%s",str[i]);
scanf("%d",&q);
for(int i=; i<q; ++i) //存下来,倒着增加边
{
scanf("%d %d",&xx1[i],&yy1[i]);
str[xx1[i]][yy1[i]]='';
}
printf("%d\n",Solve(n,m,q));
}
return ;
}

HDU 5652 India and China Origins(经典并查集)的更多相关文章

  1. HDU 5652 India and China Origins 二分+并查集

    India and China Origins 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5652 Description A long time ...

  2. HDU 5652 India and China Origins(并查集)

    India and China Origins Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/ ...

  3. 并查集(逆序处理):HDU 5652 India and China Origins

    India and China Origins Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/ ...

  4. hdu 5652 India and China Origins 并查集+二分

    India and China Origins Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/ ...

  5. hdu 5652 India and China Origins 并查集

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5652 题目大意:n*m的矩阵上,0为平原,1为山.q个询问,第i个询问给定坐标xi,yi,表示i年后这 ...

  6. (hdu)5652 India and China Origins 二分+dfs

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5652 Problem Description A long time ago there ...

  7. hdu 5652 India and China Origins 并查集+逆序

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5652 题意:一张n*m个格子的点,0表示可走,1表示堵塞.每个节点都是四方向走.开始输入初始状态方格, ...

  8. hdu5652:India and China Origins(并查集)

    倒序操作用并查集判断是否连通,新技能get√(其实以前就会了 这题细节很多...搞得整个程序都是调试输出,几度看不下去想要重写 并查集到现在大概掌握了两个基本用途:判断是否连通 / 路径压缩(上一篇b ...

  9. hdu 5652 India and China Origins 二分+bfs

    题目链接 给一个图, 由01组成, 1不能走. 给q个操作, 每个操作将一个点变为1, 问至少多少个操作之后, 图的上方和下方不联通. 二分操作, 然后bfs判联通就好了. #include < ...

随机推荐

  1. metro中stream转IRandomAccessStream

    下面的例子是从zip压缩文件解压出jpg文件流,再显示出来. StorageFile zip = await KnownFolders.PicturesLibrary.GetFileAsync(&qu ...

  2. Effective C++ -----条款28:避免返回handles指向对象内部成分

    避免返回handles(包括reference.指针.迭代器)指向对象内部.遵守这个条款可增加封装性,帮助const成员函数的行为像个const,并将发生“虚吊号码牌”(dangling handle ...

  3. DB2 SQLCODE 大全

    DB2错误信息sqlcode sqlstate 说明 000 00000 SQL语句成功完成 01xxx SQL语句成功完成,但是有警告 +012 01545 未限定的列名被解释为一个有相互关系的引用 ...

  4. 如何:使用PicturBox实现类似淘宝网站图片的局部放大功能

    转载至http://xuzhihong1987.blog.163.com/blog/static/267315872011822113131823/ 概要: 本文将讲述如何使用PictureBox控件 ...

  5. 阿里云服务器 && 如何window链接到阿里云服务器

    现在的时间是:2016年10月11日 1:购买学生机 阿里云手机app上  ->  学生专区  ->  购买: 需要注意的是:如果没有自己需要的系统,比如没有linux操作系统的ecs,那 ...

  6. ssh配置免密码登录

    日常工作中很多情况下都需要登录服务器进行管理,一般都是用ssh进行连接,为了防止密码外泄,可以配置下ssh的免密码登录. 首先服务器两台: A:43.224.34.* B:104.238.161.* ...

  7. 将rabbitmq整合到Spring中手动Ack

    如果要手动ack,需要将Listener container 的 acknowledge 设置为manul,在消费消息的类中需实现ChannelAwareMessageListener接口. over ...

  8. Android 天气曲线

    参考:http://blog.csdn.net/qy274770068/article/details/51560148

  9. c++ 头文件包含问题-include&class

    http://blog.csdn.net/jiajia4336/article/details/8996254 前向声明概念(forward declaration) 在程序中引入了类类型的B.在声明 ...

  10. poj2492(种类并查集/各种解法)

    题目链接: http://poj.org/problem?id=2492 题意: 有t组测试数据, 对于每组数据,第一行n, m分别表示昆虫的数目和接下来m行x, y, x, y表示教授判断x, y为 ...