题目链接: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. asp.net excel导出去除科学计数法的表示格式

    去除导出excel中的科学计数法的表示格式:在td标签里面加个样式:style=\"vnd.ms-excel.numberformat:@\" <td style=\&quo ...

  2. enum使用方法

    DK1.5引入了新的类型——枚举.在 Java 中它虽然算个“小”功能,却给我的开发带来了“大”方便. 用法一:常量 在JDK1.5 之前,我们定义常量都是: publicstaticfianl... ...

  3. J2SE 8的流库 --- 转换流, 得到的还是流

    流的转换, 按照条件过滤/映射/摊平/截取/丢弃/连接/去重/排序. 辅助方法 public static int myCompare(String x, String y) { if(x.lengt ...

  4. WPF 中 TextBlock 文本换行与行间距

    换行符: C#代码中:\r\n 或  \r 或 \n XAML中: 或 注:\r 回车 (carriage return 缩写),\n 新行 (new line 缩写). 行间距: LineHeigh ...

  5. MM-RGV、AGV 、IGV是什么

    RGV.AGV.IGV是什么 智能化物流仓储设备迅速崛起的时代,RGV.AGV.IGV,这三种看似有血缘关系的智能设备,到底有什么不同呢? RGV RGV即“有轨制导车辆”,又叫有轨穿梭小车,是与地面 ...

  6. jquery下的正反选操作

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. 关于AB包的释放与 Resources.UnloadUnusedAssets的关系

    Resources.UnloadUnusedAssets 并不能释放AB包中东西,只能释放从AB包中加载出来的资源,也可以释放场景中的资源,其它不是从AB包加载来的资源. AB加载后,整个包都加载到内 ...

  8. linux 一个读写锁的异常导致的故障

    环境信息: WARNING: kernel version inconsistency between vmlinux and dumpfile KERNEL: vmlinux-47.90 DUMPF ...

  9. Linux下GDB调试简单示例

    这里介绍对文件first.c的基本GDB调试操作,只有部分命令,只是一个示例,运行环境为装有gcc编译器和gdb调试器的Linux环境,基本GDB调试命令如下表: 命令                 ...

  10. [Nginx]Nginx的基本配置与优化1(完整配置示例与虚拟主机配置)

    ---------------------------------------------------------------------------------------- 完整配置示例: [ n ...