iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >详解C++图搜索算法之双端队列广搜
  • 535
分享到

详解C++图搜索算法之双端队列广搜

2024-04-02 19:04:59 535人浏览 薄情痞子
摘要

目录广度优先遍历双端队列BFS例题:AcWing 175. 电路维修解题思路AC代码广度优先遍历 广度优先遍历是一种按照层次顺序进行访问的方法,它具有以下两种重要性质: 在访问完所有

广度优先遍历

广度优先遍历是一种按照层次顺序进行访问的方法,它具有以下两种重要性质:

  • 在访问完所有第i层的结点后,才会去访问第i+1层的结点
  • 任意时刻,队列中至多有两个层次的结点。若其中一部分结点属于第i层,则另一部分结点属于第i+1层,并且所有第i层结点排在第i+1层之前。也就是说,广度优先遍历队列中的元素关于层次满足

双端队列BFS

在最基本的广度优先搜索中,每次沿着分支的扩展都记为“一步”,我们通过逐层搜索,解决了从起始状态到每个状态的最小步数的问题。这其实等价于在一张边权均为1的图上执行广度优先遍历,求出每个点相对于起点的最短距离(层次)。

由于广度优先遍历具有“两段性”和“单调性”,从而我们可以得知,每个状态在第一次被访问并且入队时,计算出的步数即为所求的最短步数。

当出现边权不是0就是1的时候,可以考虑采用双端队列BFS的方法来进行求解。

基本思路:

  • 如果拓展出来的点的边权是0的话,就添加到队头
  • 如果拓展出来的点的边权是1的话,就添加到队尾

正确性:

在通过上述的方式添加元素后,队列仍然能够满足“两段性”和“单调性”,所以所求的结果即为最短路(层次)。

例题:AcWing 175. 电路维修

达达是来自异世界的魔女,她在漫无目的地四处漂流的时候,遇到了善良的少女翰翰,从而被收留在地球上。

翰翰的家里有一辆飞行车。

有一天飞行车的电路板突然出现了故障,导致无法启动。

电路板的整体结构是一个 RR 行 CC 列的网格(R,C≤500R,C≤500),如下图所示。

每个格点都是电线的接点,每个格子都包含一个电子元件。

电子元件的主要部分是一个可旋转的、连接一条对角线上的两个接点的短电缆。

在旋转之后,它就可以连接另一条对角线的两个接点。

电路板左上角的接点接入直流电源,右下角的接点接入飞行车的发动装置。

达达发现因为某些元件的方向不小心发生了改变,电路板可能处于断路的状态。

她准备通过计算,旋转最少数量的元件,使电源与发动装置通过若干条短缆相连。

不过,电路的规模实在是太大了,达达并不擅长编程,希望你能够帮她解决这个问题。

注意:只能走斜向的线段,水平和竖直线段不能走。

输入格式

输入文件包含多组测试数据。

第一行包含一个整数 TT,表示测试数据的数目。

对于每组测试数据,第一行包含正整数 RR 和 CC,表示电路板的行数和列数。

之后 RR 行,每行 CC 个字符,字符是"/"和"\"中的一个,表示标准件的方向。

输出格式

对于每组测试数据,在单独的一行输出一个正整数,表示所需的最小旋转次数。

如果无论怎样都不能使得电源和发动机之间连通,输出 NO SOLUTioN。

数据范围

1≤R,C≤5001≤R,C≤500,

1≤T≤51≤T≤5

输入样例

1
3 5
\\/\\
\\///
/\\\\

输出样例

1

样例解释

样例的输入对应于题目描述中的情况。

只需要按照下面的方式旋转标准件,就可以使得电源和发动机之间连通。

解题思路

如图所示,用红圈所圈起来的点都是从起点出发所不能到达的(沿对角线行走的情况下)

从起点出发所能达到的点的坐标之和应为偶数,图中所圈出来的点的坐标之和均为奇数。

所以我们第一步可以使用这个性质来判断终点是否能够到达。 

然后使用双端队列来进行解答,在这道题目中对于格子和点的对应关系需要进行思考。

将电路板上的每个格点(横线和竖线的交叉点)看做是无向图中的结点。如果对角线和x到y的线段重合,则边权为0;若不重合,则边权为1。

然后在图中求出从左上角到右下角的最短距离。

踩过格子到达想去的点时,需要判断是否需要旋转电线。

若旋转电线则表示从当前点到想去的点的边权是1,若不旋转电线则边权为0。

  • dx[]和dy[]表示可以去其他点的方向
  • ix[]和iy[]表示需要踩某个方向的点才能去到相应的点
  • cs[]表示当前点走到4个方向的点理想状况下格子形状(边权是0的状态)

AC代码

#include<iOStream>
#include<deque>
#include<cstring>
#include<alGorithm>
 
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 510;
 
int n,m;
char g[N][N];
int dist[N][N];;
deque<PII> q;
 
int bfs()
{
    memset(dist,0x3f,sizeof dist);
    q.push_front({0,0});
    dist[0][0]=0;
    int dx[]={-1,-1,1,1},dy[]={-1,1,1,-1};
    int ix[]={-1,-1,0,0},iy[]={-1,0,0,-1};
 
    char s[]="\\/\\/";
 
    while(q.size())
    {
        PII t=q.front();
        q.pop_front();
        for(int i=0;i<4;i++)
        {
            int a=t.x+dx[i],b=t.y+dy[i];
            int aa=t.x+ix[i],bb=t.y+iy[i];
            if(a<0||a>n||b<0||b>m) continue;
            int d = dist[t.x][t.y]+(g[aa][bb]!=s[i]);
            if (d < dist[a][b])
            {
                dist[a][b] = d;
 
                if (g[aa][bb] != s[i]) q.push_back({a, b});
                else q.push_front({a, b});
            }
        }
    }
    return dist[n][m];
}
 
 
int main()
{   int T;
    scanf("%d", &T);
    while (T -- )
    {
        scanf("%d%d", &n, &m);
        for (int i = 0; i < n; i ++ ) scanf("%s", g[i]);
        if((n+m)%2==1) 
        {
            puts("NO SOLUTION");
            continue;
        }                
        cout<<bfs()<<endl;
    }
    return 0;
}

每个结点虽然可能被更新(入队)多次,但是它第一次被拓展(出队)时,就能得到从左上角到该点的最短距离,之后再取出可以直接忽略。

时间复杂度是O(M * N)

以上就是详解c++图搜索算法之双端队列广搜的详细内容,更多关于C++双端队列广搜的资料请关注编程网其它相关文章!

--结束END--

本文标题: 详解C++图搜索算法之双端队列广搜

本文链接: https://www.lsjlt.com/news/151430.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 详解C++图搜索算法之双端队列广搜
    目录广度优先遍历双端队列BFS例题:AcWing 175. 电路维修解题思路AC代码广度优先遍历 广度优先遍历是一种按照层次顺序进行访问的方法,它具有以下两种重要性质: 在访问完所有...
    99+
    2024-04-02
  • C++图搜索算法之双端队列广搜怎么实现
    这篇文章主要介绍“C++图搜索算法之双端队列广搜怎么实现”,在日常操作中,相信很多人在C++图搜索算法之双端队列广搜怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C++图搜索算法之双端队列广搜怎么实现...
    99+
    2023-07-02
  • java图搜索算法之DFS与BFS详解
    目录一、前言二、深度优先搜索三、广度优先搜索四、结语你好,我是小黄,一名独角兽企业的Java开发工程师。 感谢茫茫人海中我们能够相遇, 俗话说:当你的才华和能力,不足以支撑你的梦想的...
    99+
    2024-04-02
  • Java数据结构之图的两种搜索算法详解
    目录前言深度优先搜索算法API设计代码实现广度优先搜素算法API设计代码实现案例应用前言 在很多情况下,我们需要遍历图,得到图的一些性质,例如,找出图中与指定的顶点相连的所有顶点,或...
    99+
    2022-11-13
    Java数据结构 图搜索 Java 图 搜索算法 Java 数据结构 图
  • java图搜索算法之图的对象化描述示例详解
    目录一、前言二、什么是图三、怎么存储一个图的结构1、邻接矩阵2、邻接表3、图对象化表示四、图的作用你好,我是小黄,一名独角兽企业的Java开发工程师。 校招收获数十个offer,年薪...
    99+
    2024-04-02
  • Go Java算法之单词搜索示例详解
    目录单词搜索算法:DFS回溯(Java)算法:DFS回溯(Go)单词搜索 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。...
    99+
    2024-04-02
  • C++回溯算法广度优先搜索举例分析
    目录迷宫问题N叉树的层序遍历腐烂的橘子单词接龙打开转盘锁迷宫问题 假设有一个迷宫,里面有障碍物,迷宫用二维矩阵表示,标记为0的地方表示可以通过,标记为1的地方表示障碍物,不能通过。现...
    99+
    2024-04-02
  • C++回溯算法之深度优先搜索详细介绍
    目录一、前言二、基本概念1.简单介绍2. 官方概念三、动图分析四、模板框架五、例题分析组合问题题干描述思路分析一、前言 本文介绍了经典搜索算法: 深度优先搜索(DFS) 两个小故事:...
    99+
    2023-01-13
    C++深度优先搜索 C++深度优先搜索算法
  • Python数据结构与算法的双端队列详解
    目录什么是双端队列​​用Python实现双端队列运用双端队列构建回文检测器总结什么是双端队列​ 双端队列是与队列类似的有序集合。它有一前、一后两端,元素在其中保持自己的位置。与队列不...
    99+
    2024-04-02
  • Python实现线性搜索算法详解
    线性搜索是最简单的搜索算法,从数据集的开头开始,检查每一项数据,直到找到匹配项,一旦找到目标,搜索结束。 线性搜索算法的缺点 需要注意的是线性搜索算法尽管简单,但不适用数据大的情况,由于算法将每个数据一一比较,所以数据越多,耗时越...
    99+
    2024-01-23
    算法的概念
  • Vue3diff算法之双端diff算法详解
    目录双端Diff算法双端比较的原理简单Diff的不足双端Diff介绍Diff流程第一次diff第二次diff第三次diff第四次diff双端Diff的优势非理想情况的处理方式添加新元...
    99+
    2024-04-02
  • Java实现深度搜索DFS算法详解
    目录DFS概述解释思路案例题-单身的蒙蒙题目描述题解整体代码DFS概述 深度优先搜索是一种在开发爬虫早期使用较多的方法。它的目的是要达到被搜索结构的叶结点(即那些不包含任何超链的HT...
    99+
    2024-04-02
  • Python实现图的广度和深度优先路径搜索算法
    目录前言1. 图理论1.1 图的概念1.2 定义图1.3 图的抽象数据结构2. 图的存储实现2.1 邻接矩阵2.2 编码实现邻接矩阵3. 搜索路径3.1 广度优先搜索3.2 深度优先...
    99+
    2024-04-02
  • C语言数据结构之队列算法详解
    目录一、前言二、基本概念三、顺序队列四、链队列五、循环队列六、总结与提高一、前言 队列在程序设计中经常出现,如:操作系统中的排队问题。 这篇文章主要介绍了队列的...
    99+
    2024-04-02
  • Python怎么实现图的广度和深度优先路径搜索算法
    本篇内容主要讲解“Python怎么实现图的广度和深度优先路径搜索算法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python怎么实现图的广度和深度优先路径搜索算法”吧!前言图是一种抽象数据结构...
    99+
    2023-06-30
  • C语言中深度优先搜索(DFS)算法的示例详解
    目录迷宫问题思路实现代码深搜的剪枝优化可行性剪枝最优性剪枝迷宫问题 有一个迷宫: S**.....***T (其中字符S表示起点,字符T表示终点,字符*表示墙壁,字符.表示平地。你需...
    99+
    2023-02-16
    C语言深度优先搜索算法 C语言 DFS算法
  • C++数据结构之二叉搜索树的实现详解
    目录前言介绍实现节点的实现二叉搜索树的查找二叉搜索树的插入二叉搜索树的删除总结前言 今天我们来学一个新的数据结构:二叉搜索树。 介绍 二叉搜索树也称作二叉排序树,它具有以下性质: 非...
    99+
    2024-04-02
  • Python图像处理之图像增广算法详解
    目录前言图像增广算法a.图像旋转b.图像亮度调整c.图像裁剪及拼接本章小结前言 图像增广算法在计算机视觉领域扮演着至关重要的角色。随着深度学习的兴起,大规模数据集的需求变得更加迫切,...
    99+
    2023-05-20
    Python图像增广算法 Python图像处理 Python 算法
  • Java C++ 算法题解leetcode669修剪二叉搜索树示例
    目录题目要求思路一:模拟迭代JavaC++思路二:递归JavaC++Rust题目要求 思路一:模拟迭代 依次判断每个节点是否合法:首先找出结果的根,若原根小了就拉右边的过来,大了...
    99+
    2024-04-02
  • C++示例详解Prim算法与优先队列
    目录Prim算法prim代码实现优先队列优先队列代码实现自定义类型优先序列贪心算法的本质是:一个问题的局部最优解,也是该问题的全局最优解。 最小生成树的最优子结构性质:假设一个无向图...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作