小z的洞穴之旅 QDUOJ 并查集+连通块
小z的洞穴之旅 QDUOJ 并查集+连通块
题意
小 z 同学在某个闲暇的周末决定去野外探险一波,结果在丛林深处中误打误撞进入了一个神秘的洞穴,虽然洞穴中光线昏暗,但小 z 凭借其敏锐的眼力立刻辨认出这是一个迷宫状洞穴,并且他还发现了一个现象:该洞穴中时不时会有一个墙块自行坍塌,每个墙体坍塌后其所在单元格即变为空地,其坍塌过程中所产生的尘土也会随之传到该墙体相连的各个空地处,于是他很好奇,对于每一次墙块的坍塌,所产生的尘土会遍及到多大的空白区域?
解题思路
这个题很像《啊哈!算法》中的岛屿问题,但是如果每次有墙倒塌后都进行BFS一次的话会超时,所以这里要先进行预处理,这里预处理是用bfs来扫,把联通的块使用并查集归并到一起(对于二维的数据,需要转化为一维的数据,代码中的getid函数就是干这个的)。之后每次有墙倒塌就查看周围四个位置, 详情见代码实现。
在此也感谢ZYB学长的题解!当时没有尝试做,很忏愧。
代码实现
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=5e3+7;
struct note{
int fa, sum;
}tre[maxn*maxn];
struct node{
int x, y;
};
int n, m;
char mp[maxn][maxn];
int go[4][2]={1, 0, 0, 1, -1, 0, 0, -1};
queue<node> q;
inline int getid(int x, int y)// getid()将二维点(x,y)映射为一维的数值
{
return (x-1)*m + y;
}
int find(int x) //寻找父节点,并且进行路径压缩
{
if(tre[x].fa==x) return x;
else return tre[x].fa = find(tre[x].fa);
}
void merge(int u, int v) //这里合并时按照各自集合中点的个数来进行合并
{
u=find(u);
v=find(v);
if(u==v) return ;
if(tre[u].sum >= tre[v].sum)
{
tre[v].fa=u;
tre[u].sum+=tre[v].sum;
}
else {
tre[u].fa=v;
tre[v].sum+=tre[u].sum;
}
}
void bfs(int x, int y, int rt) //预处理中的一部分
{
while(!q.empty()) q.pop() ;
node h={x, y}, tmp;
int tx, ty, id;
q.push(h);
while(!q.empty())
{
h=q.front();
q.pop() ;
for(int i=0; i<4; i++)
{
tx=h.x+go[i][0];
ty=h.y+go[i][1];
if(tx<=0 || tx>n || ty<=0 || ty>m || mp[tx][ty]=='#')
continue;
id=getid(tx, ty);
if(tx==x && ty==y || tre[id].fa!=id) continue;
merge(rt, id);
tmp.x=tx;
tmp.y=ty;
q.push(tmp);
}
}
}
void init() //预处理的主程序
{
int id;
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
{
id=getid(i, j);
tre[id].fa=id; //默认父节点都是自己
tre[id].sum=1;//默认个数都是1
}
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
{
id=getid(i, j);
// fa[tmp]!=tmp即表示该块已被遍历过
if(mp[i][j]=='#' || tre[id].fa != id) continue;
bfs(i, j, id);
}
}
int main()
{
int q, x, y, tx, ty, id, tmp;
scanf("%d%d", &n, &m);
for(int i=1; i<=n; i++)
scanf("%s", mp[i]+1);
init();
scanf("%d", &q);
while(q--)
{
scanf("%d%d", &x, &y);
id=getid(x, y);
//尝试将(x,y)点与周围上下左右四个区域合并
for(int i=0; i<4; i++)
{
tx=x+go[i][0];
ty=y+go[i][1];
if(tx<=0 || tx>n || ty<=0 || ty>m || mp[tx][ty]=='#')
continue;
tmp=getid(tx, ty);
merge(id, tmp);
}
mp[x][y]='.'; //最后还需要维护原始的mp[][]
printf("%d\n", tre[find(id)].sum); //返回当前点(x,y)所在的连通块的大小
}
return 0;
}
小z的洞穴之旅 QDUOJ 并查集+连通块的更多相关文章
- 【BZOJ】2049: [Sdoi2008]Cave 洞穴勘测(lct/并查集)
http://www.lydsy.com/JudgeOnline/problem.php?id=2049 bzoj挂了..在wikioi提交,,1A-写lct的速度越来越快了-都不用debug-- 新 ...
- BZOJ_2049_[Sdoi_2008]_Cave_洞穴勘测_(LCT/并查集)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=2049 给出一个森林,起始互不相连,现在有link和cut两种操作,问x,y是否在一棵树里. 分 ...
- 小Z的城市之旅
题目大意: 从(0,0)走到(x,y),每次可以向上下左右走一格,问走r步刚好到(x,y)的方案数. 思路: 找规律发现答案就是C((r+x-y)/2,r)*C((r-x-y)/2,r). #incl ...
- BZOJ 2038: [2009国家集训队]小Z的袜子(hose) [莫队算法]【学习笔记】
2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 7687 Solved: 3516[Subm ...
- BZOJ 2038: [2009国家集训队]小Z的袜子(hose)
2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 Sec Memory Limit: 259 MBSubmit: 7676 Solved: 3509[Subm ...
- BZOJ2038: [2009国家集训队]小Z的袜子(hose)
Time Limit: 20 Sec Memory Limit: 259 MB Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天, ...
- Bzoj 2038---[2009国家集训队]小Z的袜子(hose) 莫队算法
题目链接 http://www.lydsy.com/JudgeOnline/problem.php?id=2038 Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色 ...
- 莫队算法 2038: [2009国家集训队]小Z的袜子(hose)
链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2038 2038: [2009国家集训队]小Z的袜子(hose) Time Limit: 20 ...
- BZOJ 2038 小z的袜子 & 莫队算法(不就是个暴力么..)
题意: 给一段序列,询问一个区间,求出区间中.....woc! 贴原题! 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过 ...
随机推荐
- JavaScript 中的 for 循环---------------引用
在ECMAScript5(简称 ES5)中,有三种 for 循环,分别是: 简单for循环 for-in forEach 下面先来看看大家最常见的一种写法: 当数组长度在循环过程中不会改变时,我们应将 ...
- excel解决日常问题记录
=MOD(ROW(),2)和=TEXT(B2487-B2486,"[h]:mm:ss"),我利用excel分析出了延迟的数据 比较2个字符串是否一样:=EXACT(A2,F2) 公 ...
- 15. ClustrixDB 管理数据分布
本节使用的关键术语: Relation — ClustrixDB中的每个表都被称为“关系”. Representation — 在ClustrixDB中,每个索引都称为一个“Representatio ...
- 配置中心Apollo多环境部署
- android stadio gradle问题
https://www.jianshu.com/p/2bb0b6a7b479 https://www.jianshu.com/p/d175bef9770c Unable to resolve depe ...
- UVa 1601 || POJ 3523 The Morning after Halloween (BFS || 双向BFS && 降维 && 状压)
题意 :w*h(w,h≤16)网格上有n(n≤3)个小写字母(代表鬼).要求把它们分别移动到对应的大写字母里.每步可以有多个鬼同时移动(均为往上下左右4个方向之一移动),但每步结束之后任何两个鬼不能占 ...
- 51Nod 1413 权势二进制 (思维)
题意 : 一个十进制整数被叫做权势二进制, 当他的十进制表示的时候只由0或1组成.例如0, 1, 101, 110011都是权势二进制而2, 12, 900不是.当给定一个n (1<=n< ...
- 【BZOJ3811/UOJ36】 玛里苟斯
Description 魔法之龙玛里苟斯最近在为加基森拍卖师的削弱而感到伤心,于是他想了一道数学题. S 是一个可重集合,S={a1,a2,…,an}. 等概率随机取 S 的一个子集 A={ai1,… ...
- install_github无法安装 Rwebdriver包的解决方法
1.通过install_githtb安装Rwebdriver包的错误如下: 提示不能打开URL,但是将URL地址输入浏览器地址栏,则可以下载包到本地 2.在网上搜索,发现可以通过本地文件来安装(ins ...
- 请简述一下 Ajax 的原理及实现步骤
简述 AJAX:AJAX即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术.通过在后台与服务器进行 ...