题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5652

题意:

  输入T,接下来T个样例,每个样例输入n,m代表图的大小,接下来n行,每行m个数,代表图,0表示这个位置可以走,1表示走不了,接下来q个点的位置,表示第q个时间这个点的值变成1,就不能走了,问在什么时间开始从最上面无法走到最下面。

最后还是看了别人博客(不争气啊),用并查集的思路就是先给每个点编号,然后用两个数组pre1,pre2数组方便存储编号为i的点所在的点集(并查集)里面最左和最右的值,当最左的值为0,最右的值为m-1是说明这个连续的点集已经把上下隔断了。只是大致说了下,看代码,有人也用了二分+BFS,对q个时间段进行二分,用BFS判断上下是否被隔断,应该是这样,没用这种方法写。

代码:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
#include<stack>
#include<cmath>
#include<vector>
#include<set>
#include<cstdio>
#include<string>
#include<deque>
using namespace std;
typedef long long LL;
#define eps 1e-8
#define INF 0x3f3f3f3f
#define maxn 505
int n,m,k,t,ans,id;
char str[maxn][maxn];
int num[maxn][maxn];//记录点str[i][j]对应的编号
int pre1[maxn*maxn],pre2[maxn*maxn];//两个数组记录祖先,祖先编号对m取模得出的值就是左右两边最值
int dir[][]={,,,-,,,-,,,,,-,-,,-,-};//八个方向
int find1(int a)
{
if(a==pre1[a])
return a;
return pre1[a]=find1(pre1[a]);
}
void combine1(int x,int y)
{
int a=find1(x);
int b=find1(y);
if(a%m<b%m)//祖先编号对m取模值较小的为合并之后的祖先
pre1[b]=a;
else
pre1[a]=b;
}
int find2(int a)
{
if(a==pre2[a])
return a;
return pre2[a]=find2(pre2[a]);
}
void combine2(int x,int y)
{
int a=find2(x);
int b=find2(y);
if(a%m>b%m)//祖先编号对m取模值较大的为合并之后的祖先
pre2[b]=a;
else
pre2[a]=b;
}
void bianhao()
{
for(int i=;i<n;i++)
{
for(int j=;j<m;j++)
{
num[i][j]=++id;//给每个点编号
pre1[id]=id;
pre2[id]=id;
}
}
for(int i=;i<n;i++)
{
for(int j=;j<m;j++)
{
if(str[i][j]=='')
{
for(int k=;k<;k++)//搜索每个黑块周围
{
int a=i+dir[k][];
int b=j+dir[k][];
if(a>=&&a<n&&b>=&&b<m&&str[a][b]=='')
{
combine1(num[i][j],num[a][b]);
combine2(num[i][j],num[a][b]);
}
}
}
}
}
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
ans=-;
id=-;
for(int i=;i<n;i++)
scanf("%s",str[i]);
bianhao();
for(int i=;i<n;i++)
{
for(int j=;j<m;j++)
{
int a=find1(num[i][j]);
int b=find2(num[i][j]);
if(a%m==&&b%m==m-)//在山峰升起前可能两国可能已经隔断
{
ans=;
break;
}
}
if(ans!=-)
break;
}
int q;
scanf("%d",&q);
for(int s=;s<=q;s++)
{
int x,y;
scanf("%d%d",&x,&y);
str[x][y]='';//山峰升起
if(ans!=-)
continue;
for(int i=;i<;i++)
{
int a=x+dir[i][];
int b=y+dir[i][];
if(a>=&&a<n&&b>=&&b<m&&str[a][b]=='')
{
combine1(num[x][y],num[a][b]);
combine2(num[x][y],num[a][b]);
int l=find1(num[x][y]);
int r=find2(num[x][y]);
if(l%m==&&r%m==m-)//黑色块所在点集的左右两最值达到左右边界
{
ans=s;
break;
}
}
}
}
printf("%d\n",ans);
}
return ;
}

思维+并查集 hdu5652的更多相关文章

  1. Gym - 101243F Vitamins(思维+并查集)

    题意 有三种药丸,白色W>红色R>蓝色B,给你m个约束条件,问你n个药丸的颜色,不能确定颜色输出‘?’ 题解 如果1<2<3,只要找到2就能确定1和3的颜色 如果2=4,只要确 ...

  2. cf 之lis+贪心+思维+并查集

    https://codeforces.com/contest/1257/problem/E 题意:有三个集合集合里面的数字可以随意变换位置,不同集合的数字,如从第一个A集合取一个数字到B集合那操作数+ ...

  3. 牛客网多校第4场 J Hash Function 【思维+并查集建边】

    题目链接:戳这里 学习博客:戳这里 题意: 有n个空位,给一个数x,如果x%n位数空的,就把x放上去,如果不是空的,就看(x+1)%n是不是空的. 现在给一个已经放过数的状态,求放数字的顺序.(要求字 ...

  4. codeforces 1013B 【思维+并查集建边】

    题目链接:戳这里 转自:参考博客 题意:给一个n*m的矩阵,放入q个点,这q个点之间的关系是,若已知这样三个点(x1,y1),(x2,y1),(x1,y2),可以在(x2,y2)处生成一个新的点,对于 ...

  5. CodeForces - 1243D (思维+并查集)

    题意 https://vjudge.net/problem/CodeForces-1243D 有一张完全图,n个节点 有m条边的边权为1,其余的都为0 这m条边会给你 问你这张图的最小生成树的权值 思 ...

  6. hdu5652 India and China Origins(并查集)

    India and China Origins  Accepts: 49  Submissions: 426  Time Limit: 2000/2000 MS (Java/Others)  Memo ...

  7. hdu6074[并查集+LCA+思维] 2017多校4

    看了标答感觉思路清晰了许多,用并查集来维护全联通块的点数和边权和. 用另一个up[]数组(也是并查集)来保证每条边不会被重复附权值,这样我们只要将询问按权值从小到大排序,一定能的到最小的边权和与联通块 ...

  8. 【春训团队赛第四场】补题 | MST上倍增 | LCA | DAG上最长路 | 思维 | 素数筛 | 找规律 | 计几 | 背包 | 并查集

    春训团队赛第四场 ID A B C D E F G H I J K L M AC O O O O O O O O O 补题 ? ? O O 传送门 题目链接(CF Gym102021) 题解链接(pd ...

  9. CF思维联系--CodeForces - 218C E - Ice Skating (并查集)

    题目地址:24道CF的DIv2 CD题有兴趣可以做一下. ACM思维题训练集合 Bajtek is learning to skate on ice. He's a beginner, so his ...

随机推荐

  1. python selenium 三种等待方式详解[转]

    python selenium 三种等待方式详解   引言: 当你觉得你的定位没有问题,但是却直接报了元素不可见,那你就可以考虑是不是因为程序运行太快或者页面加载太慢造成了元素不可见,那就必须要加等待 ...

  2. 选择、操作web元素-2

    11月3日 等待web元素的出现 例子:百度搜索松勤网,点击操作后不等待页面刷新,下面选择页面元素的时候,该元素还是未出现 sleep方案的弊病:固定的等待时间,导致测试用例执行时间很长 为什么cli ...

  3. 对String值不可变的理解以及String类型的引用传递问题

    今天复习java时,突然注意到了一句以前没有注意过的一句话,String 是final修饰的,其值是不可变的.当时看的一脸懵逼,String str = "abc"; str = ...

  4. Rust语言学习笔记(5)

    Structs(结构体) struct User { username: String, email: String, sign_in_count: u64, active: bool, } let ...

  5. 循环取到json中的字段数据,加到html中

    $.ajax({ type:'post', data:{specialName:specialName,count:count}, url:"admin/pcAdminGetArticleL ...

  6. android布局管理器

    1 LinearLayout (线性布局) 让所有的组件都成为单一的方向,机垂直的或水平的(默认). android:Layout_weight //该属性控制水平和垂直方向某个控件所占比例. 2.F ...

  7. ERROR: dump failed because assets could not be loaded

    在命令行输入命令,想查看到app的包名,报错,如下: D:\测试\测试\android-sdk_r16-windows\android-sdk-windows\platform-tools>aa ...

  8. CSS 颜色

    color属性可以指定HTML文本的颜色. HTML的颜色采用以下3种方式表示. RGB值 使用红色.绿色.蓝色等不同比例表示,如 1 rgb(100,90,90) 值在0~255之间. 十六进制编码 ...

  9. 判断用户 是用的电脑还是手机 判断 是安卓还是IOS

    $(function(){ var Terminal = { // 辨别移动终端类型 platform: function () { var u = navigator.userAgent, app ...

  10. <assert.h>库学习

    assert的初步认识 assert宏指令是用来诊断程序是否有误的,函数原型如下 void assert(int expression) 那为什么我们要使用assert而不用printf呢?因为ass ...