题目链接: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. flex学习笔记 使用函数,显示实时更新的标签

    <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="ht ...

  2. pycharm中查找替换妙用

    1.二行空格变一行(转载https://www.cnblogs.com/dreamfine/p/7760575.html) 网上COPY的代码,经常多出一个空行,不用一行行删除了,用替换功能吧,查找 ...

  3. leetcode1021

    class Solution(object): def removeOuterParentheses(self, S: str) -> str: li = list() bcode = 0 te ...

  4. 网关、子网掩码、DHCP, DNS

    都跟ip地址相关,IP地址构成:网络地址+主机地址 子网掩码可以确定网络地址,例如某IP:192.168.1.102 子网掩码:255.255.255.0, 那么网络地址就是192.168.1,主机地 ...

  5. 与前端对接 jsonp

    主要是回调的写法,前端人员接受的数据格式      参数 (jsonString);

  6. 修改 计算机名后,修改SQLserver 注册服务器对象的名称,及登陆名

    select @@ServerName --查看当前所有数据库服务器名称select * from Sys.SysServers --修改数据库服务器名称sp_dropserver 'old_serv ...

  7. redisclient can not connect

    假如采用传统请执行一下命令: systemctl stop firewalld systemctl mask firewalld 并且安装iptables-services: yum install ...

  8. [ SHELL编程 ] 数组、关联数组和awk数组

    本文主要对shell编程中常用的数组.关联数组和awk数组定义.操作以及注意事项做个总结,并提供具体案例. 数组 数组定义:一对圆括号表示数组,数组元素之间用空格符号分割. Array=(val1 v ...

  9. LeetCode OJ 94. Binary Tree Inorder Traversal

    Given a binary tree, return the inorder traversal of its nodes' values. For example:Given binary tre ...

  10. [jQ]jQuery显式操作Checkbox,并用数组存储关联值的方案

    ---------------------------------------------------------------------------------------------------- ...