题意:两个人玩很变态的游戏,将一个草坪的某两个点点燃,点燃的草坪可以向上下左右四个方向扩散,问能否将整块草坪上面的草都点燃。如果能,输出最短时间(^_^他们就能玩更变态的游戏了),如果不能,输出-1.

思路:先求整个草坪的联通块数量cnt。

1.如果cnt大于2,一定不能点燃全图,输出-1

2.如果cnt等于2,分别在两个联通块枚举每个点中找最短时间,最后答案就是max(time1, time2)

3.如果cnt等于1,此题的关键点。枚举两个点作为bfs的两个起点,注意是两个起点,bfs求在这个两块中,到达任意一点至少需要的时间。最后的答案就是枚举的所有情况的最小时间。 PS:我用了另外一种判断最小时间,没考虑到一种特殊情况错了一下午。

AC代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int maxn = 15;

char G[maxn][maxn];
int vis[maxn][maxn], d[maxn][maxn];

const int dx[] = {1,-1,0,0};
const int dy[] = {0,0,-1,1};

int n, m;

void dfs(int x, int y, int flag) {
	vis[x][y] = flag;
	for(int i = 0; i < 4; ++i){
		int px = x + dx[i], py = y + dy[i];
		if(px < 0 || py < 0 || px >= n || py >= m) continue;
		if(G[px][py] == '#' && !vis[px][py]) dfs(px, py, flag);
	}
}

int bfs(int x, int y, int xx, int yy){
	memset(d, -1, sizeof(d));
	int ans = 0;
	queue<int>q;
	q.push(x * m + y);
	q.push(xx * m + yy);
	d[x][y] = d[xx][yy] = 0;
	while(!q.empty()) {
		int pos = q.front();
		q.pop();
		x = pos / m, y = pos % m;
		for(int i = 0; i < 4; ++i){
			int px = x + dx[i], py = y + dy[i];
			if(px < 0 || py < 0 || px >= n || py >= m) continue;
			if(G[px][py] == '#' && d[px][py] == -1){
				d[px][py] = d[x][y] + 1;
				q.push(px * m + py);
				ans = max(ans, d[px][py]);
			}
		}
	}
	return ans;
}

int main(){
	int T;
	scanf("%d", &T);
	int kase = 1;
	while(T--){

		scanf("%d%d", &n, &m);
		for(int i = 0; i < n; ++i) scanf("%s", G[i]);

		printf("Case %d: ", kase++);

		memset(vis, 0, sizeof(vis));
		int cnt = 0;
		for(int i = 0; i < n; ++i)
		for(int j = 0; j < m; ++j) {
			if(G[i][j] == '#' && !vis[i][j]) {
				++cnt;
				dfs(i, j, cnt);
			}
		}
		if(cnt > 2) printf("-1\n");

		else if(cnt == 2) {
			int inf = 1 << 30;
			int ans[] = {inf, inf};
			for(int i = 0; i < n; ++i)
			for(int j = 0; j < m; ++j){
				if(G[i][j] == '#') {
					int h = vis[i][j] - 1;
					int a = bfs(i, j, i, j);
					ans[h] = min(ans[h], a);
				}

			}
			printf("%d\n", max(ans[0], ans[1]));
		}

		else if(cnt == 1){
			int ans = 1 << 30;
			for(int i = 0; i < n * m; ++i) {
				int x1 = i / m, y1 = i % m;
				if(G[x1][y1] != '#') continue;
				for(int j = i + 1; j < n * m; ++j) {
					int x2 = j / m, y2 = j % m;
					if(G[x2][y2]!= '#') continue;
					int h = bfs(x1, y1, x2, y2);
					ans = min(ans, h);
				}

			}

			if(ans == 1 << 30) ans = 0;
			printf("%d\n", ans);
		}
		else if(cnt == 0) printf("-1\n");
	}

	return 0;
}

如有不当之处欢迎指出!

FZU - 2150 bfs [kuangbin带你飞]专题一的更多相关文章

  1. HDU - 3533 bfs [kuangbin带你飞]专题二

    看了好久的样例才看懂. 题意:有一个人要从(0,0)走到(n,m),图中有k个碉堡,每个碉堡可以向某个固定的方向每隔t秒放一次炮,炮弹不能穿越另一个碉堡,会被阻挡.人在移动的过程中不会被炮弹打到,也就 ...

  2. HDU - 2102 A计划 (BFS) [kuangbin带你飞]专题二

    思路:接BFS判断能否在限制时间内到达公主的位置,注意如果骑士进入传送机就会被立即传送到另一层,不会能再向四周移动了,例如第一层的位置(x, y, 1)是传送机,第二层(x, y, 2)也是传送机,这 ...

  3. UVA - 11624 多点bfs [kuangbin带你飞]专题一

    题意:某人身陷火场,总有k个点着火,着火点可向四周扩散,问此人能否逃离. 思路:可能有多个着火点,以这些着火点作为起点进行bfs,得到整个火场的最短距离,然后又以人所在坐标作为起点进行bfs,得到该人 ...

  4. POJ - 2251 bfs [kuangbin带你飞]专题一

    立体bfs,共有六个方向: const int dx[] = {0,0,1,-1,0,0}; const int dy[] = {1,-1,0,0,0,0}; const int dz[] = {0, ...

  5. POJ - 3414 bfs [kuangbin带你飞]专题一

    状态搜索,每种状态下面共有六种选择,将搜索到的状态保存即可. d[i][j]表示状态A杯中水i升,B杯中水j升,总状态数量不会超过A杯的容量 * B杯的容量. AC代码 #include<cst ...

  6. POJ - 3984 bfs [kuangbin带你飞]专题一

    bfs搜索过程中将路径保存下即可. AC代码 #include<cstdio> #include<cstring> #include<algorithm> #inc ...

  7. HDU - 2612 bfs [kuangbin带你飞]专题一

    分别以两个人的家作为起点,bfs求得到每个KFC最短距离.然后枚举每个KFC,求得时间之和的最小值即可. 此题不符合实际情况之处:  通过了一个KFC再去另一个KFC可以吗? 出题人都没好好想过吗? ...

  8. HDU - 1495 bfs [kuangbin带你飞]专题一

    模拟倒水的过程,每次可以把第i个杯子的水向第j个杯子里面倒,这可能出现新的状态,不停的更新状态,指导某两个杯子的水等于S/2说明找到答案,如果所有状态搜索完毕仍然不能均分,则退出. 注意:如果S是奇数 ...

  9. HDU - 1241 dfs or bfs [kuangbin带你飞]专题一

    8个方向求联通块,经典问题. AC代码 #include<cstdio> #include<cstring> #include<algorithm> #includ ...

随机推荐

  1. Python输出hello world(各行命令详解)

    创建main.py文件并粘贴下面代码 点击右键运行Debug 'main'后,下方的Debug窗口会出现ImportError: No module named 'bottle'这样的提示,提示导入b ...

  2. TOMCAT原理详解及请求过程

    Tomcat: Tomcat是一个JSP/Servlet容器.其作为Servlet容器,有三种工作模式:独立的Servlet容器.进程内的Servlet容器和进程外的Servlet容器. Tomcat ...

  3. 【转】 要做linux运维工程师的朋友,必须要掌握以下几个工具才行

          本人是linux运维工程师,对这方面有点心得,现在我说说要掌握哪方面的工具吧 说到工具,在行外可以说是技能,在行内我们一般称为工具,就是运维必须要掌握的工具. 我就大概列出这几方面,这样入 ...

  4. Node-debug方法

    本文使用配置node-inspector配合chorme完成debug(编辑器使用SublimeText3). 1.用命令行进入安装node的目录,使用npm install -g node-insp ...

  5. Sql Server的艺术(一) 视图的增删查改

    视图是从一个或者多个表中查询数据的另一种方式.利用视图可以集中.简化定制数据库,同时还能保障安全. 视图其结构和数据是建立在对应的查询基础上的.和表一样,视图也是包括几个被定义的数据列和多个数据行,但 ...

  6. 浅谈大型web系统架构(一)

    目录 Web前端系统 负载均衡系统 数据库集群系统 缓存系统 分布式存储系统 分布式服务器管理系统 代码发布系统   动态应用,是相对于网站静态内容而言,是指以c/c++.php.Java.perl. ...

  7. python3操作redis

    redis也被称为缓存 1.redis是一个key-value存储系统,没有ForeignKey和ManyToMany的字段. 2.在redis中创建的数据彼此之间是没有关系的,所以也被称为是非关系型 ...

  8. 在CentOS7上实现NFS共享

    一.介绍 NFS 是Network File System的缩写,即网络文件系统.一种使用于分散式文件系统的协定,功能是让客户端通过网络访问不同主机上磁盘里的数据,主要用在类Unix系统上实现文件共享 ...

  9. wxpython发布还自己图标的程序

    在py2exe安装脚本文件中,修改代码: setup( windows=[ { 'script': 'myapp.py', 'icon_resources': [(1, 'myicon.ico')] ...

  10. 17年年终总结——走过2017,迎来2018Flag

    引言 记得大概从大学毕业到现在都没有写作啥总结性的文章了(ps:应该是没写过啥长篇大论了),所以也不知道怎么个起头.我也闲聊的方式起头吧. 其实跨入18年就想着写篇总结,总结下自己17年的得与失,不足 ...