E. Two Labyrinths

Time Limit: 20 Sec

Memory Limit: 256 MB

题目连接

http://codeforces.com/gym/100187/problem/E

Description

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 size n × 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 these n 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 Input

3 5
.....
.#.#.
.....

.....
#.#.#
.....

Sample Output

YES

HINT

 

题意

问你是否存在一条路,在两个迷宫都合法,而且都是最短路呢?

题解:

3次bfs,第一次bfs找到第一个迷宫的最短路,第二次bfs找到第二个迷宫的最短路,第三次bfs求共同的最短路

代码

#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <typeinfo>
#include <fstream>
#include <map>
#include <stack>
typedef long long ll;
using namespace std;
//freopen("D.in","r",stdin);
//freopen("D.out","w",stdout);
#define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
#define test freopen("test.txt","r",stdin)
#define maxn 2000001
#define mod 10007
#define eps 1e-9
const int inf=0x3f3f3f3f;
const ll infll = 0x3f3f3f3f3f3f3f3fLL;
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
//**************************************************************************************

int a1[510][510];
int a2[510][510];
string s;
struct node
{
    int x,y,z;
};
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
int vis[510][510];
int main()
{
    int n=read(),m=read();
    for(int i=0;i<n;i++)
    {
        cin>>s;
        for(int j=0;j<m;j++)
        {
            if(s[j]=='.')
                a1[i][j]=1;
            else
                a1[i][j]=0;
        }
    }
    for(int i=0;i<n;i++)
    {
        cin>>s;
        for(int j=0;j<m;j++)
        {
            if(s[j]=='.')
                a2[i][j]=1;
            else
                a2[i][j]=0;
        }
    }
    queue<node> q;
    q.push((node){0,0,0});
    int flag=0;
    int ans1=inf;
    memset(vis,0,sizeof(vis));
    vis[0][0]=1;
    while(!q.empty())
    {
        node now=q.front();
        q.pop();
        if(now.x==n-1&&now.y==m-1&&ans1>now.z)
        {
            ans1=now.z;
            continue;
        }
        for(int i=0;i<4;i++)
        {
            node next;
            next.x=now.x+dx[i];
            next.y=now.y+dy[i];
            next.z=now.z;
            if(next.x<0||next.x>=n)
                continue;
            if(next.y<0||next.y>=m)
                continue;
            if(vis[next.x][next.y]||a1[next.x][next.y]==0)
                continue;
            vis[next.x][next.y]=1;
            q.push((node){next.x,next.y,next.z+1});
        }
    }
    while(!q.empty())
        q.pop();
    q.push((node){0,0,0});
    int ans2=inf;
    memset(vis,0,sizeof(vis));
    vis[0][0]=1;
    while(!q.empty())
    {
        node now=q.front();
        q.pop();
        if(now.x==n-1&&now.y==m-1&&ans2>now.z)
        {
            ans2=now.z;
            continue;
        }
        for(int i=0;i<4;i++)
        {
            node next;
            next.x=now.x+dx[i];
            next.y=now.y+dy[i];
            next.z=now.z;
            if(next.x<0||next.x>=n)
                continue;
            if(next.y<0||next.y>=m)
                continue;
            if(vis[next.x][next.y]||a2[next.x][next.y]==0)
                continue;
            vis[next.x][next.y]=1;
            q.push((node){next.x,next.y,next.z+1});
        }
    }

    if(ans1!=ans2)
    {
        puts("NO");
        return 0;
    }
    while(!q.empty())
        q.pop();
    q.push((node){0,0,0});
    memset(vis,0,sizeof(vis));
    vis[0][0]=1;

    while(!q.empty())
    {
        if(flag)
            break;
        node now=q.front();
        q.pop();
        if(now.x==n-1&&now.y==m-1&&now.z==ans1)
            flag=1;
        if(flag)
            break;
        for(int i=0;i<4;i++)
        {
            node next;
            next.x=now.x+dx[i];
            next.y=now.y+dy[i];
            next.z=now.z+1;
            if(next.x<0||next.x>=n)
                continue;
            if(next.y<0||next.y>=m)
                continue;
            if(vis[next.x][next.y]||a1[next.x][next.y]==0||a2[next.x][next.y]==0)
                continue;
            vis[next.x][next.y]=1;
            q.push((node){next.x,next.y,next.z});
        }
    }
    if(flag)
        puts("YES");
    else
        puts("NO");


}

 

Time Limit: 20 Sec

Memory Limit: 256 MB

题目连接

http://codeforces.com/gym/100187/problem/E

Description

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 size n × 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 these n 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 Input

3 5
.....
.#.#.
.....

.....
#.#.#
.....

Sample Output

YES

HINT

 

题意

问你是否存在一条路,在两个迷宫都合法,而且都是最短路呢?

题解:

3次bfs,第一次bfs找到第一个迷宫的最短路,第二次bfs找到第二个迷宫的最短路,第三次bfs求共同的最短路

代码

#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <typeinfo>
#include <fstream>
#include <map>
#include <stack>
typedef long long ll;
using namespace std;
//freopen("D.in","r",stdin);
//freopen("D.out","w",stdout);
#define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
#define test freopen("test.txt","r",stdin)
#define maxn 2000001
#define mod 10007
#define eps 1e-9
const int inf=0x3f3f3f3f;
const ll infll = 0x3f3f3f3f3f3f3f3fLL;
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
//**************************************************************************************

int a1[510][510];
int a2[510][510];
string s;
struct node
{
    int x,y,z;
};
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
int vis[510][510];
int main()
{
    int n=read(),m=read();
    for(int i=0;i<n;i++)
    {
        cin>>s;
        for(int j=0;j<m;j++)
        {
            if(s[j]=='.')
                a1[i][j]=1;
            else
                a1[i][j]=0;
        }
    }
    for(int i=0;i<n;i++)
    {
        cin>>s;
        for(int j=0;j<m;j++)
        {
            if(s[j]=='.')
                a2[i][j]=1;
            else
                a2[i][j]=0;
        }
    }
    queue<node> q;
    q.push((node){0,0,0});
    int flag=0;
    int ans1=inf;
    memset(vis,0,sizeof(vis));
    vis[0][0]=1;
    while(!q.empty())
    {
        node now=q.front();
        q.pop();
        if(now.x==n-1&&now.y==m-1&&ans1>now.z)
        {
            ans1=now.z;
            continue;
        }
        for(int i=0;i<4;i++)
        {
            node next;
            next.x=now.x+dx[i];
            next.y=now.y+dy[i];
            next.z=now.z;
            if(next.x<0||next.x>=n)
                continue;
            if(next.y<0||next.y>=m)
                continue;
            if(vis[next.x][next.y]||a1[next.x][next.y]==0)
                continue;
            vis[next.x][next.y]=1;
            q.push((node){next.x,next.y,next.z+1});
        }
    }
    while(!q.empty())
        q.pop();
    q.push((node){0,0,0});
    int ans2=inf;
    memset(vis,0,sizeof(vis));
    vis[0][0]=1;
    while(!q.empty())
    {
        node now=q.front();
        q.pop();
        if(now.x==n-1&&now.y==m-1&&ans2>now.z)
        {
            ans2=now.z;
            continue;
        }
        for(int i=0;i<4;i++)
        {
            node next;
            next.x=now.x+dx[i];
            next.y=now.y+dy[i];
            next.z=now.z;
            if(next.x<0||next.x>=n)
                continue;
            if(next.y<0||next.y>=m)
                continue;
            if(vis[next.x][next.y]||a2[next.x][next.y]==0)
                continue;
            vis[next.x][next.y]=1;
            q.push((node){next.x,next.y,next.z+1});
        }
    }

    if(ans1!=ans2)
    {
        puts("NO");
        return 0;
    }
    while(!q.empty())
        q.pop();
    q.push((node){0,0,0});
    memset(vis,0,sizeof(vis));
    vis[0][0]=1;

    while(!q.empty())
    {
        if(flag)
            break;
        node now=q.front();
        q.pop();
        if(now.x==n-1&&now.y==m-1&&now.z==ans1)
            flag=1;
        if(flag)
            break;
        for(int i=0;i<4;i++)
        {
            node next;
            next.x=now.x+dx[i];
            next.y=now.y+dy[i];
            next.z=now.z+1;
            if(next.x<0||next.x>=n)
                continue;
            if(next.y<0||next.y>=m)
                continue;
            if(vis[next.x][next.y]||a1[next.x][next.y]==0||a2[next.x][next.y]==0)
                continue;
            vis[next.x][next.y]=1;
            q.push((node){next.x,next.y,next.z});
        }
    }
    if(flag)
        puts("YES");
    else
        puts("NO");


}