双向dfs,多次dfs

前言:这个答案给我们提供了一种多次dfs的思路,记录queue的size,每次只取size个,就刚刚好只处理了上一次的‘


题目地址

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;

//定义队列节点
struct node
{
    int x,y;
}rear,front;
//Q[0]为小B进行BFS的队列,Q[1]为小A进行BFS的队列
queue<node>Q[2];
//ans表示双方碰面时间
int ans=0,N,M,dx[]={0,0,1,-1,1,1,-1,-1},dy[]={1,-1,0,0,1,-1,1,-1};
char R[1005][1005];
//Flag表示是否能碰面,V[0][][]为小B的标记数组,V[1][][]为小A的标记数组
bool Flag=0,V[2][1005][1005]={0};
//参数a为0表示小B进行BFS,为1则是小A进行BFS
bool BFS(bool a)
{
    int i,x,y,q=Q[a].size();
    //将该时刻能走到的所有位置出队搜索
    while(q--)
    {
        front=Q[a].front(),Q[a].pop();
        //若a为1,那么小A要进行8个方向的搜索
        for(i=0;i<4+(a?4:0);i++)
        {
            x=front.x+dx[i],y=front.y+dy[i];
            //越界或者碰见障碍或者走回头路都是非法的
            if(x<0||x>=N||y<0||y>=M||R[x][y]=='#'||V[a][x][y])continue;
            //若碰见对方走过的路,令Flag置1,同时返回1
            if(V[!a][x][y])return Flag=1;
            //下个位置入队
            V[a][x][y]=1,rear.x=x,rear.y=y,Q[a].push(rear);
        }
    }
    //若未碰见对方,返回0
    return 0;
}
int main()
{
    int i,j,x1,y1,x2,y2;
    scanf("%d%d",&N,&M);
    //接收地图,记录小A与小B的起点
    for(i=0;i<N;i++)
        for(j=0;j<M;j++)
        {
            scanf(" %c",&R[i][j]);
            if(R[i][j]=='D')x1=i,y1=j;
            if(R[i][j]=='C')x2=i,y2=j;
        }

    rear.x=x1,rear.y=y1,V[0][x1][y1]=1,Q[0].push(rear);
    rear.x=x2,rear.y=y2,V[1][x2][y2]=1,Q[1].push(rear);
    //每秒小B进行BFS两次,而小A进行BFS一次
    while(!Q[0].empty()||!Q[1].empty())
    {
        ans++;
        //一旦碰到对方立马跳出循环
        if(BFS(0))break;
        if(BFS(0))break;
        if(BFS(1))break;
    }
    if(Flag)printf("YES\n%d\n",ans);
    else printf("NO\n");
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
这是一个典型的图论问题,我们可以使用深度优先搜索(DFS)或广度优先搜索(BFS)来解决。由于我们需要避免重复访问同一景点,所以我们需要记录每个节点是否被访问过。 具体思路如下: 1. 选择一个起点,标记为已访问。 2. 对于当前节点,遍历与其相连的所有未访问节点。 3. 对于每个未访问节点,将其标记为已访问,并将其添加到路径中。 4. 递归遍历该节点,并更新最大路径长度。 5. 当遍历完所有未访问节点后,将该节点从路径中删除,并标记为未访问。 6. 返回上一层递归,继续遍历其他未访问节点。 7. 重复步骤2-6,直到遍历完所有起点。 代码如下: ```python def dfs(node, visited, path, max_len, graph): visited[node] = True path.append(node) for neighbor in graph[node]: if not visited[neighbor]: visited[neighbor] = True path.append(neighbor) dfs(neighbor, visited, path, max_len, graph) path.pop() visited[neighbor] = False if len(path) > max_len: max_len = len(path) visited[node] = False path.pop() return max_len def find_longest_path(n, edges): graph = [[] for _ in range(n+1)] for u, v in edges: graph[u].append(v) graph[v].append(u) max_len = 0 for i in range(1, n+1): visited = [False] * (n+1) max_len = dfs(i, visited, [], max_len, graph) return max_len ``` 其中,n为景点总数,edges为景点之间的双向路。我们使用邻接表来存储图。调用函数`find_longest_path`即可找到最长路径的长度。 注意,这里的时间复杂度为O(n^2),可能无法处理较大的数据。可以使用剪枝等优化方法来提高效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wniuniu_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值