Codeforces Gym 100187 E. Two Labyrinths (双图BFS找共同最短路)

E. Two Labyrinths
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

A labyrinth is the rectangular grid, each of the cells of which is either free or wall, and it's possible to move only between free cells sharing a side.

Constantine and Mike are the world leaders of composing the labyrinths. Each of them has just composed one labyrinth of sizen × m, and now they are blaming each other for the plagiarism. They consider that the plagiarism takes place if there exists such a path from the upper-left cell to the lower-right cell that is the shortest for both labyrinths. Resolve their conflict and say if the plagiarism took place.

Input

In the first line two integers n and m (1 ≤ n, m ≤ 500) are written — the height and the width of the labyrinths.

In the next n lines the labyrinth composed by Constantine is written. Each of thesen lines consists of m characters. Each character is equal either to «#», which denotes a wall, or to «.», which denotes a free cell.

The next line is empty, and in the next n lines the labyrinth composed by Mike is written in the same format. It is guaranteed that the upper-left and the lower-right cells of both labyrinths are free.

Output

Output «YES» if there exists such a path from the upper-left to the lower-right cell that is the shortest for both labyrinths. Otherwise output «NO».

Sample test(s)
Input
3 5
.....
.#.#.
.....
  

.....
#.#.#
.....
Output
NO
Input
3 5
.....
.#.##
.....
  

.....
##.#.
.....
Output
YES


题意:给你两个图,问两个图从(0,0)到(n-1,m-1)的最短路径是否相同

思路:用三次BFS,第一次寻找第一个图的最短路,第二次找第二个图的最短路,第三次查看两个图的最短路径是否相同。

这道题让我知道细心是多么重要,WA了10次,在同一组数据上,和傻逼一样查错查了一个半小时,换了几个姿势,最后发现就因为标记数组的大小写错了,就是开数组的时候少按了一个5,一个5,一个5啊,当时找的想撞墙了。。找出来之后简直是想吐血啊啊啊啊啊。。。



ac代码:
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stack>
#include<set>
#include<queue>
#include<vector>
#define MAXN 1010000
#define LL long long
#define ll __int64
#include<iostream>
#include<algorithm>
#define INF 0x7fffffff
#define mem(x) memset(x,0,sizeof(x))
#define PI acos(-1)
using namespace std;
LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
LL lcm(LL a,LL b){return a/gcd(a,b)*b;}
ll powmod(ll a,LL b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
//head
char map[3][555][555];
int v[3][555][555];//就是这里,写成了v[3][555][55]
int vis[555][555];
int cnt[3];
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int n,m;
int bz;
struct s
{
	int x,y,step;
};
int check(int kk,int xx,int yy)
{
	if(xx<0||xx>=n||yy<0||yy>=m)
	return 0;
	if(v[kk][xx][yy]||map[kk][xx][yy]=='#')
	return 0;
	return 1;
}
queue<s>q;
void bfs(int k)
{
	while(!q.empty())
	q.pop();
	s a,b;
	a.x=0;a.y=0;a.step=0;
	v[k][0][0]=1;
	q.push(a);
	while(!q.empty())
	{
		a=q.front();
		q.pop();
		if(a.x==n-1&&a.y==m-1&&a.step<cnt[k])
		{
			cnt[k]=a.step;
			continue;
		}
		for(int i=0;i<4;i++)
		{
			b.x=a.x+dir[i][0];
			b.y=a.y+dir[i][1];
			if(check(k,b.x,b.y))
			{
				b.step=a.step+1;
				v[k][b.x][b.y]=1;
				//printf("debug\n");
				q.push(b);
			}
		}
	}
}
void bbfs()
{
	while(!q.empty())
	q.pop();
	s a,b;
	a.x=0;a.y=0;a.step=0;
	vis[0][0]=1;
	q.push(a);
	while(!q.empty())
	{
		if(bz)
		break;
		a=q.front();
		q.pop();
		if(a.x==n-1&&a.y==m-1&&a.step==cnt[1])
		{
			bz=1;
			break;
		}
		for(int i=0;i<4;i++)
		{
			b.x=a.x+dir[i][0];
			b.y=a.y+dir[i][1];
			if(b.x>=0&&b.x<n&&b.y>=0&&b.y<m&&!vis[b.x][b.y]&&map[0][b.x][b.y]=='.'&&map[1][b.x][b.y]=='.')
			{
				b.step=a.step+1;
				vis[b.x][b.y]=1;
				q.push(b);
			}
		}
	}
}
int main()
{
	int i;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		mem(map);
		for(i=0;i<n;i++)
		scanf("%s",map[0][i]);
		for(i=0;i<n;i++)
		scanf("%s",map[1][i]);
		mem(v);
		cnt[0]=INF;cnt[1]=INF;
		bfs(0);
		bfs(1);
		//printf("%d %d\n",cnt[0],cnt[1]);
		if(cnt[0]!=cnt[1])
		{
			printf("NO\n");
			continue;
		}
		bz=0;
		mem(vis);
		bbfs();
		if(bz)
		printf("YES\n");
		else
		printf("NO\n");
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值