Gym - 100187E E - Two Labyrinths —— bfs

本文解析了 CodeForces 题目 E 的解决方案,通过两次 BFS 分别计算两张地图的最短路径,并在最短路径相同的前提下,合并地图再次进行 BFS 验证是否可以达到相同路径长度的终点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:http://codeforces.com/gym/100187/problem/E


题解:一开始做的时候是将两幅图合并,然后直接bfs看是否能到达终点。但这种做法的错的,因为走出来的路对于两幅图来说不一定都是最短的。正确做法:

第一步:分别用bfs求出两图的最短路。

第二步:如果最短路长度一样。则将两幅图合并,再bfs,如果能走到终点,且最短路长度仍然等于未合并前的长度,则YES; 否则NO。


学习之处: 求两个或多个事物所共有的东西,其实就是求交集


代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<map>
#include<string>
#include<set>
//#define LOCAL
using namespace std;
#define pb push_back
#define ms(a, b) memset(a,b,sizeof(a));
typedef long long LL;
const int inf = 0x3f3f3f3f;
const int mod = 1000000007;
const int maxn = 10;

struct node
{
    int x,y,k;
};
node now, e;

int n,m, vis[550][550];
char a[550][550], b[550][550], c[550][550];
int d[4][2] = {1,0,-1,0,0,1,0,-1};

int bfs(int x, int y, char s[][550])
{
    queue<node>q;
    memset(vis,0,sizeof(vis));
    now.x = x;
    now.y = y;
    now.k = 0;
    vis[x][y] = 1;
    q.push(now);

    while(!q.empty())
    {
        now = q.front();
        q.pop();

        if(now.x==n && now.y==m)
                return now.k;

        for(int i = 0; i<4; i++)
        {
            e.x = now.x + d[i][0];
            e.y = now.y + d[i][1];
            e.k = now.k + 1;

            if(e.x<1 || e.x>n || e.y<1 || e.y>m || vis[e.x][e.y] || s[e.x][e.y]=='#')
                continue;
                
            vis[e.x][e.y] = 1;
            q.push(e);
        }
    }
    return -1;
}

int main()
{

    cin>>n>>m;
    for(int i = 1; i<=n; i++)
        scanf("%s",a[i]+1);

    for(int i = 1; i<=n; i++)
        scanf("%s",b[i]+1);

    for(int i = 1; i<=n; i++)
    for(int j = 1; j<=m; j++)
    {
        if(a[i][j]=='#' || b[i][j]=='#')
            c[i][j] = '#';
        else
            c[i][j] = '.';
    }

    int B = 0;
    int t1 = bfs(1,1,a);//分别搜两幅图的最短路
    int t2 = bfs(1,1,b);
    if(t1 == t2 && t1 !=-1)//在最短路的前提下,再找两图合并的最短路是否存在并是否为原来的值
    {
        if( bfs(1,1,c)== t1 )
            B = 1;
    }

    if(B)
        puts("YES");
    else
        puts("NO");
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值