引爆炸弹——DFS&&联通块
题目
在一个$n \times m$方格地图上,某些方格上放置着炸弹。手动引爆一个炸弹以后,炸弹会把炸弹所在的行和列上的所有炸弹引爆,被引爆的炸弹又能引爆其他炸弹,这样连锁下去。
现在为了引爆地图上的所有炸弹,需要手动引爆其中一些炸弹,为了把危险程度降到最低,请算出最少手动引爆多少个炸弹可以把地图上的所有炸弹引爆。

解决方案
由于炸弹连锁,问题等价于求图中的联通块,只是此处的不只是相邻的炸弹联通,同行或同列也是广义的联通。
值得注意的是,寻找“相邻”炸弹时不能挨个查找(会超时),需要先预处理每个炸弹的“东”、“西”、“南”、“北”相邻炸弹的位置。
#include<bits/stdc++.h>
using namespace std; const int maxn = + ;
const int maxm = + ;
int n,m;
bool maze[maxn][maxm];
bool r[maxn], c[maxm];
char s[maxm];
int dn[maxn][maxm], ds[maxn][maxm], dw[maxn][maxm], de[maxn][maxm]; void init()
{
//memset(dn, -1, sizeof(dn));
//memset(ds, -1, sizeof(ds));
//memset(dw, -1, sizeof(dw));
//memset(de, -1, sizeof(de));
for(int j = ;j < m;j++)
{
int flagn = -;
for(int i = ;i < n;i++)
{
dn[i][j] = flagn;
if(maze[i][j] == ) flagn = i;
}
} for(int j = ;j < m;j++)
{
int flags = -;
for(int i = n-;i >= ;i--)
{
ds[i][j] = flags;
if(maze[i][j] == ) flags = i;
}
} for(int i = ;i < n;i++)
{
int flagw = -;
for(int j = ;j < m;j++)
{
dw[i][j] = flagw;
if(maze[i][j] == ) flagw = j;
}
} for(int i = ;i < n;i++)
{
int flage = -;
for(int j = m - ;j >= ;j--)
{
de[i][j] = flage;
if(maze[i][j] == ) flage = j;
}
}
} int cnt = ;
void dfs(int i, int j)
{
//printf("%d %d\n", i, j);
maze[i][j] = ;
r[i] = c[j] = true; if(dn[i][j] != - && maze[dn[i][j]][j] == ) dfs(dn[i][j], j);
if(ds[i][j] != - && maze[ds[i][j]][j] == ) dfs(ds[i][j], j);
if(dw[i][j] != - && maze[i][dw[i][j]] == ) dfs(i, dw[i][j]);
if(de[i][j] != - && maze[i][de[i][j]] == ) dfs(i, de[i][j]); } int main()
{
scanf("%d%d", &n,&m);
for(int i = ;i < n;i++)
{
scanf("%s", s);
for(int j = ;j < m;j++) maze[i][j] = s[j] - '';
} init(); int ans = ;
for(int i = ;i <n;i++)
for(int j = ;j < m;j++)
{
if(maze[i][j] == && (!r[i]) && (!c[j])) //出现过的行和列肯定不可能再存在“未爆炸”的炸弹
{
dfs(i, j);
ans++;
}
}
printf("%d\n", ans); return ;
}
引爆炸弹——DFS&&联通块的更多相关文章
- Educational Codeforces Round 5 - C. The Labyrinth (dfs联通块操作)
题目链接:http://codeforces.com/contest/616/problem/C 题意就是 给你一个n行m列的图,让你求’*‘这个元素上下左右相连的连续的’.‘有多少(本身也算一个), ...
- 蓝桥杯模拟赛-引爆炸弹-DFS+并查集
今天整理电脑,翻出来了很久以前大佬给的题,贴一下. 引爆炸弹 1000ms 在一个 n×m的方格地图上,某些方格上放置着炸弹.手动引爆一个炸弹以后,炸弹会把炸弹所在的行和列上的所有炸弹引爆,被引爆的炸 ...
- Codeforces277A 【dfs联通块】
题意: 给出n个人会的语言类型,然后问这n个人里面还需要几个人学习一下语言就可以n个直接互通了.a会1,2,b会2,3,c会4,那么只要C学一下1或者2,或者3就好了...大致就是这个意思. 思路: ...
- hdoj2952【DFS联通块】
我觉得还是这种不带回溯的直接搜到底的好玩啊!!!但是要注意边界,记得以前四周要空出来的一道题目,被坑了很久,还是wa到比赛结束!!!这道还是基础题 类似的基础题:POJ1562 hdoj1016 po ...
- Codeforces Round #369 (Div. 2) D. Directed Roads dfs求某个联通块的在环上的点的数量
D. Directed Roads ZS the Coder and Chris the Baboon has explored Udayland for quite some time. The ...
- HDU - 1213 dfs求联通块or并查集
思路:给定一个无向图,判断有几个联通块. AC代码 #include <cstdio> #include <cmath> #include <algorithm> ...
- 【紫书】Oil Deposits UVA - 572 dfs求联通块
题意:给你一个地图,求联通块的数量. 题解: for(所有还未标记的‘@’点) 边dfs边在vis数组标记id,直到不能继续dfs. 输出id及可: ac代码: #define _CRT_SECURE ...
- 分别利用并查集,DFS和BFS方法求联通块的数量
联通块是指给定n个点,输入a,b(1<=a,b<=n),然后将a,b连接,凡是连接在一起的所有数就是一个联通块: 题意:第一行输入n,m,分别表示有n个数,有输入m对连接点,以下将要输入m ...
- 蓝桥杯模拟赛 引爆炸弹-并查集+DFS
引爆炸弹 在一个 n×m的方格地图上,某些方格上放置着炸弹.手动引爆一个炸弹以后,炸弹会把炸弹所在的行和列上的所有炸弹引爆,被引爆的炸弹又能引爆其他炸弹,这样连锁下去. 现在为了引爆地图上的所有炸弹, ...
随机推荐
- POJ3311 Hie with the Pie 【状压dp/TSP问题】
题目链接:http://poj.org/problem?id=3311 Hie with the Pie Time Limit: 2000MS Memory Limit: 65536K Total ...
- 【leetcode算法-简单】1.两数之和
[题目描述] 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重复利用这个 ...
- java基础知识入门
一.java简介及原理图 Java的前世今生 Java之父詹姆斯·高斯林: 1967年, 12岁用报废的电话机和电视做了一台电子游戏机; 1983年, 获得卡内基梅隆大学计算机科学博士学位; 1983 ...
- RMI(远程方法调用)
Remote Method Invocation 跨虚拟机间调用 使用 RMI 技术可轻松将 服务提供者(Service Provider)与 服务消费者(Service Consumer)进行分离 ...
- 【数据库-SQL Server】IDispatch error #3092
使用msado15.tlh,链接Microsoft SQL Server,执行语法(syntax)的时候出现IDispatch error #3092的错误. 1.语法错误 (1)保证语法正确,有些数 ...
- fiddler笔记:统计选项卡(Statistics)
Request Count 选中的Session数. Bytes sent Http请求头和请求体中向外发送的字节总数. Bytes received HTTP请求头和请求体中接收到的所有字节数. R ...
- Pygame小游戏练习三
@Python编程从入门到实践 Python项目练习 七.创建Passenger类 创建passenger.py文件,创建Passenger类,控制乘客属性和行为 # passenger.py imp ...
- linux下nginx搭建
1.准备 1-1.安装 make,zlib,gcc-c++,openssl yum -y install make zlib zlib-devel gcc-c++ libtool openssl o ...
- 一、python快速入门(每个知识点后包含练习)
1. 编程与编程语言 编程的目的是什么? #计算机的发明,是为了用机器取代/解放人力,而编程的目的则是将人类的思想流程按照某种能够被计算机识别的表达方式传递给计算机,从而达到让计算机能够像人脑/电脑一 ...
- luogu P4762 [CERC2014]Virus synthesis (回文自动机)
大意: 初始有一个空串, 操作(1)在开头或末尾添加一个字符. 操作(2)在开头或末尾添加该串的逆串. 求得到串$S$所需最少操作数. 显然最后一定是由某个偶回文通过添加字符得到的, 那么只需要求出所 ...