BFS中的多源BFS、最小步数模型和双端队列广搜

多源BFS

多源BFS时有从多个源点出发的bfs算法,只需要将多个源点都连一条边权为0的边到虚拟源点,那么问题就等价于从虚拟源点开始BFS。

一开始直接将所有源点加入BFS的队列即可.

173. 矩阵距离

给定一个 N N N M M M 列的 01 01 01 矩阵 A A A A [ i ] [ j ] A[i][j] A[i][j][j] 与 A [ k ] [ l ] A[k][l] A[k][l] 之间的曼哈顿距离定义为: d i s t ( i , j , k , l ) = ∣ i − k ∣ + ∣ j − l ∣ dist(i,j,k,l)=|i−k|+|j−l| dist(i,j,k,l)=ik+jl

输出一个 N N N M M M 列的整数矩阵 B B B,其中: B [ i ] [ j ] = m i n 1 ≤ x ≤ N , 1 ≤ y ≤ M , A [ x ] [ y ] = 1 d i s t ( i , j , x , y ) B[i][j]=min_{1≤x≤N,1≤y≤M,A[x][y]=1}dist(i,j,x,y) B[i][j]=min1xN,1yM,A[x][y]=1dist(i,j,x,y)

输入格式

第一行两个整数 N , M N,M N,M

接下来一个 N N N M M M 列的 01 01 01 矩阵,数字之间没有空格。

输出格式

一个 N N N M M M 列的矩阵 B B B,相邻两个整数之间用一个空格隔开。

数据范围

1 ≤ N , M ≤ 1000 1≤N,M≤1000 1N,M1000

输入样例:
3 4
0001
0011
0110
输出样例:
3 2 1 0
2 1 0 0
1 0 0 1

思路:

  • 本题目的意思就是求出所有点到 1 1 1 的最短距离
  • 首先将所有的点 1 1 1 坐标放入队列中,进行多源 BFS
#include<iostream>
#include<queue>
using namespace std;
typedef pair<int,int> PII;
const int N = 1010;
int n, m, dist[N][N], dx[5] = {0, -1, 1, 0, 0}, dy[5] = {0, 0, 0, -1, 1};
char g[N][N];
bool st[N][N];
queue<PII> q;void bfs(){while(q.size()){auto t = q.front();q.pop();int x = t.first, y = t.second;for (int i = 1; i <= 4; i++){int tx = x + dx[i], ty = y + dy[i];if(tx < 0 || tx >= n || ty < 0 || ty >= m || st[tx][ty]) continue;dist[tx][ty] = dist[x][y] + 1;q.push({tx, ty});st[tx][ty] = true;}}for (int i = 0; i < n; i++){for (int j = 0; j < m; j++){if(j) cout << " " << dist[i][j];else cout << dist[i][j];}cout << endl;}
}int main(){cin >> n >> m;for (int i = 0; i < n; i++){cin >> g[i];for (int j = 0; j < m; j++){if(g[i][j] == '1'){q.push({i, j});st[i][j] = true;}}}bfs();return 0;
}

最小步数模型

1107. 魔板

Rubik 先生在发明了风靡全球的魔方之后,又发明了它的二维版本——魔板。

这是一张有 8 8 8 个大小相同的格子的魔板:

1 2 3 4
8 7 6 5

我们知道魔板的每一个方格都有一种颜色。

8 8 8 种颜色用前 8 8 8 个正整数来表示。

可以用颜色的序列来表示一种魔板状态,规定从魔板的左上角开始,沿顺时针方向依次取出整数,构成一个颜色序列。

对于上图的魔板状态,我们用序列 ( 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ) (1,2,3,4,5,6,7,8) (1,2,3,4,5,6,7,8) 来表示,这是基本状态。

这里提供三种基本操作,分别用大写字母 A,B,C 来表示(可以通过这些操作改变魔板的状态):

A:交换上下两行;
B:将最右边的一列插入到最左边;
C:魔板中央对的4个数作顺时针旋转。

下面是对基本状态进行操作的示范:

A:

8 7 6 5
1 2 3 4

B:

4 1 2 3
5 8 7 6

C:

1 7 2 4
8 6 3 5

对于每种可能的状态,这三种基本操作都可以使用。

你要编程计算用最少的基本操作完成基本状态到特殊状态的转换,输出基本操作序列。

注意:数据保证一定有解。

输入格式

输入仅一行,包括 8 8 8 个整数,用空格分开,表示目标状态。

输出格式

输出文件的第一行包括一个整数,表示最短操作序列的长度。

如果操作序列的长度大于0,则在第二行输出字典序最小的操作序列。

数据范围

输入数据中的所有数字均为 1 1 1 8 8 8 之间的整数。

输入样例:
2 6 8 4 5 7 3 1
输出样例:
7
BCABCCB
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<algorithm>
using namespace std;
typedef pair<string, string> PII;
string source = "12345678", target;string move1(string s){reverse(s.begin(), s.end());return s;
}string move2(string s){return s[3] + s.substr(0, 3) + s.substr(5, 3) + s[4];
}string move3(string s){swap(s[1], s[2]);swap(s[5], s[6]);swap(s[1], s[5]);return s;
}void bfs(){map<string, int> mp;queue<PII> q;q.push({source, ""});mp[source] = 1;while(q.size()){auto t = q.front();q.pop();string state = t.first, step = t.second;if(state == target){cout << step.length() << endl;if(step.length()) cout << step << endl;return ;}string tstate = move1(state);if(!mp[tstate]){q.push({tstate, step + "A"});mp[tstate] = 1;}tstate = move2(state);if(!mp[tstate]){q.push({tstate, step + "B"});mp[tstate] = 1;}tstate = move3(state);if(!mp[tstate]){q.push({tstate, step + "C"});mp[tstate] = 1;}}
}int main(){for (int i = 1; i <= 8; i++){string n;cin >> n;target = target + n;}bfs();return 0;
}

双端队列广搜

双端队列广搜主要解决图中边的权值只有0或者1的最短路问题,注意和多源BFS不一样,这种是无法用连虚拟源点那种做法的。

双端队列广搜中,边权为0的点放到队头,边权为1的点放到队尾,这样队列仍然满足单调性,且形式上和普通广搜一样,前面的点和后面的点距离相差为1。

普通bfs判断终点,在入队就时就能算出最小距离,双端队列广搜必须在出队时才知道点的最小值。因为有可能终点入队是被距离为1的边入的,后面的点可能会搜到离终点距离为0的边让其入队,故入队时不一定是最小距离,但出队时一定是。

**操作:**每次从队头取出元素,并进行拓展其他元素时

  1. 若拓展某一元素的边权是 0 0 0,则将该元素插入到队头
  2. 若拓展某一元素的边权是 1 1 1,则将该元素插入到队尾

与堆优化Dijkstra 一样,必须在出队时才知道每个点最终的最小值,而和一般的bfs不一样,原因是如下图所示

175. 电路维修

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

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

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

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

电路.png

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

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

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

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

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

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

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

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

输入格式

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

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

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

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

输出格式

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

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

数据范围

1 ≤ R , C ≤ 500 1≤R,C≤500 1R,C500,
1 ≤ T ≤ 5 1≤T≤5 1T5

输入样例:
1
3 5
\\/\\
\\///
/\\\\
输出样例:
1
样例解释

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

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

电路2.png

思路:

  • 首先明确的一点是,这里是图中的格子和点是不一样的,点是格子上的角角上的点,每个点都有4个方向可以走,分别对应的是左上角,右上角,右下角,左下角

  • 踩过格子到达想去的点时,需要判断是否需要旋转电线,若旋转电线表示从 当前点 到 想去的点 的边权是 1 1 1,若不旋转电线则边权是 0 0 0

  • 按左上角,右上角,右下角,左下角遍历的顺序

    1. dx[]dy[]表示可以去其他点的方向
    2. id[]iy[]表示需要踩某个方向的各种才能去到相应的点
    3. cs[]表示当前点走到 4 4 4 个方向的点理想状态下格子形状(边权是 0 0 0 的状态)
#include<iostream>
#include<deque>
#include<cstring>
using namespace std;
const int N = 510;
typedef pair<int,int> PII;
int t, n, m, dist[N][N];
char g[N][N];
bool st[N][N];void bfs(){memset(dist, 0x3f, sizeof dist);memset(st, false, sizeof st);int dx[4] = {-1, -1, 1, 1}, dy[4] = {-1, 1, 1, -1}, ix[4] = {-1, -1, 0, 0}, iy[4] = {-1, 0, 0, -1};char s[5] = "\\/\\/";deque<PII> q;q.push_back({0, 0});dist[0][0] = 0;while(q.size()){auto t = q.front();q.pop_front();int x = t.first, y = t.second;if(x == n && y == m){cout << dist[x][y] << endl;return;}if(st[x][y]) continue;for (int i = 0; i < 4; i++){int tx = x + dx[i], ty = y + dy[i];if(tx < 0 || tx > n || ty < 0 || ty > m) continue;int xx = x + ix[i], yy = y + iy[i];int w = (g[xx][yy] != s[i]);if(dist[tx][ty] > dist[x][y] + w){dist[tx][ty] = dist[x][y] + w;if(w) q.push_back({tx, ty});else q.push_front({tx, ty});}}}
}int main(){cin >> t;while(t--){cin >> n >> m;for (int i = 0; i < n; i++) cin >> g[i];if(n + m & 1) puts("NO SOLUTION");else bfs();}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/65317.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分布式版本管理工具——git 中忽略文件的版本跟踪(初级方法及高级方法)

git工具忽略指定文件的版本跟踪 一、简单方式实现二、复杂方式实现&#xff08;模式匹配&#xff09;1. 相关规则2. 应用案例a) 忽略所有内容b) 忽略所有目录&#xff08;不忽略当前目录的具体文件&#xff09;c)忽略指定目录下的所有文件&#xff0c;但排除某文件d&#xff09…

1225. 报告系统状态的连续日期 - 力扣(LeetCode)

目录 1. 力扣链接 2. 题目 3. 分析 4. 代码实现 5. 代码验证 6. 总结 1. 力扣链接 1225. 报告系统状态的连续日期 - 力扣&#xff08;LeetCode&#xff09; 2. 题目 表&#xff1a;Failed ----------------------- | Column Name | Type | -----------------------…

jenkins集成工具(一)部署php项目

目录 什么是CI 、CD Jenkins集成工具 一、Jenkins介绍 二、jenkins的安装和部署 环境部署 安装jenkins 安装gitlab 配置镜像源进行安装 修改密码 安装git工具 上传测试代码 Jenkins部署php项目wordpress 发布php代码 安装插件 测试代码发布 实现发布成功发送邮件…

STM32F103RCT6学习之一:基本开发流程

开发方式 1.基于寄存器开发---与51类似 2.基于标准库开发----基于寄存器进行函数的封装 3.基于HAL库开发----对标准库进行更深入的封装&#xff0c;有句柄、回调函数等概念 STM32Cube 一种STM32硬件配置开发工具&#xff0c;可根据需要生成项目模版 1.选择芯片 2.配置管…

汽车IVI中控开发入门及进阶(46):FFmpeg

概述: FFmpeg 是领先的多媒体框架,能够解码、编码、 转码、复用、解复用、流、过滤和播放 几乎所有人类和机器创建的东西。它支持最模糊的古老格式,直到最前沿。无论它们是由某个标准委员会、社区还是公司设计的。它还具有高度的可移植性:FFmpeg 在各种构建环境、机器架构…

.NET平台用C#通过字节流动态操作Excel文件

在.NET开发中&#xff0c;通过字节流动态操作Excel文件提供了一种高效且灵活的方式处理数据。这种方法允许开发者直接在内存中创建、修改和保存Excel文档&#xff0c;无需依赖直接的文件储存、读取操作&#xff0c;从而提高了程序的性能和安全性。使用流技术处理Excel不仅简化了…

Word论文交叉引用一键上标

Word论文交叉引用一键上标 1.进入Microsoft word使用CtrlH快捷键或单击替换按钮 2.在查找内容中输入[^#] 3.鼠标点击&#xff0c;标签为“替换为&#xff1a;”的文本框&#xff0c;注意光标一定要打在图红色方框圈中的文本框中&#xff01; 4.点击格式选择字体 5.勾选上标…

直流有刷电机多环控制(PID闭环死区和积分分离)

直流有刷电机多环控制 提高部分-第8讲 直流有刷电机多环控制实现(1)_哔哩哔哩_bilibili PID模型 外环的输出作为内环的输入,外环是最主要控制的效果,主要控制电机的位置。改变位置可以改变速度,改变速度是受电流控制。 实验环境 【 !】功能简介: 按下KEY1使能电机,按下…

计算机网络实验室建设方案

一、计算机网络实验室拓扑结构 计算机网络综合实验室解决方案&#xff0c;是面向高校网络相关专业开展教学实训的综合实训基地解决方案。教学实训系统采用 B&#xff0f;S架构&#xff0c;通过公有云教学实训平台在线学习模式&#xff0c;轻松实现网络系统建设与运维技术的教学…

soular使用教程

用 soular 配置你的组织&#xff0c;工作更高效&#xff01;以下是快速上手的简单步骤&#xff1a; &#xfeff; 1. 账号管理 可以对账号信息进行多方面管理&#xff0c;包括分配不同的部门、用户组等&#xff0c;从而确保账号权限和职责的清晰分配。 &#xfeff; 1.1 用…

FPGA的DMA应用——pcileech

硬件通过pcie总线&#xff0c;访存本机的内存&#xff0c;并进行修改&#xff0c;可以进行很多操作。 学习视频&#xff1a;乱讲DMA及TLP 1-pcileech项目简介和自定义模块介绍_哔哩哔哩_bilibili vivado2024.1的下载文章链接和地址&#xff1a;AMD-Xilinx Vivado™ 2024.1 现…

原点安全再次入选信通院 2024 大数据“星河”案例

近日&#xff0c;中国信息通信研究院和中国通信标准化协会大数据技术标准推进委员会&#xff08;CCSA TC601&#xff09;共同组织开展的 2024 大数据“星河&#xff08;Galaxy&#xff09;”案例征集活动结果正式公布。由工银瑞信基金管理有限公司、北京原点数安科技有限公司联…

Log4j2的Policies详解、SizeBasedTriggeringPolicy、TimeBasedTriggeringPolicy

文章目录 一、Policies二、SizeBasedTriggeringPolicy:基于文件大小的滚动策略2.1、文件达到指定大小就归档 三、TimeBasedTriggeringPolicy&#xff1a;基于时间间隔的滚动策略3.1、验证秒钟归档场景3.2、验证分钟场景3.3、验证小时场景 四、多策略组合使用五、扩展知识5.1、S…

【机器学习与数据挖掘实战】案例06:基于Apriori算法的餐饮企业菜品关联分析

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈机器学习与数据挖掘实战 ⌋ ⌋ ⌋ 机器学习是人工智能的一个分支,专注于让计算机系统通过数据学习和改进。它利用统计和计算方法,使模型能够从数据中自动提取特征并做出预测或决策。数据挖掘则是从大型数据集中发现模式、关联…

EleutherAI/pythia-70m

EleutherAI/pythia-70m” 是由 EleutherAI 开发的一个小型开源语言模型&#xff0c;它是 Pythia Scaling Suite 系列中参数量最小的模型&#xff0c;拥有大约 7000 万个参数。这个模型主要旨在促进对语言模型可解释性的研究&#xff1b; Pythia Scaling Suite是为促进可解释性…

在国产电脑上运行PDFSAM软件使用pdf分割合并交替混合处理pdf文档

软件下载地址: https://sourceforge.net/projects/pdfsam/files/ 需要注意事项&#xff0c;系统需要java环境&#xff0c;确认系统有java环境&#xff0c;根据软件版本需求安装对应的java运行环境。 下载pdfsam-4.3.4-linux.tar.gz安装包&#xff0c;解压&#xff0c;将runt…

【HENU】河南大学计院2024 计算机网络 期末复习知识点

和光同尘_我的个人主页 一直游到海水变蓝。 计网复习 第一章互联网组成类别交换方式分组交换的要点&#xff1a;分组交换的优点&#xff1a; 网络性能指标体系结构网络协议五层协议 第二章&#xff1a;物理层物理层的主要任务&#xff08;四大特性&#xff09;通信的三种方式…

python网络框架——Django、Tornado、Flask和Twisted

Django、Tornado和flask是全栈网络框架&#xff0c;而Twisted更专注于网络底层的高性能封装&#xff0c;不提供HTML模版引擎等界面功能&#xff0c;因此不能称为全栈框架。 1、Django 发布于2003年&#xff0c;是当前python世界里最负盛名且最成熟的网络框架。相较于其他web框…

C++——运算符重载

一、运算符重载 ①含义 函数重载或函数多态&#xff1a;同名函数完成相同的基本操作 C将重载的概念扩展到运算符上&#xff0c;于是出现了运算符重载 C中有很多运算符已经被重载 *运算符&#xff0c;运用于地址&#xff0c;可以得到存储在这个地址的值&#xff1b;运用于两个…

IPv6的地址类型

IPv6地址总长度为128bit&#xff0c;被分为8组&#xff0c;每组为4个十六进制数&#xff0c;用冒号分隔&#xff1a; 例如&#xff1a;FC00:0123:4567:8901:ABFD:0987:0000:0023 可缩写为&#xff1a;FC00:0123:4567:8901:ABFD:0987::23 IPv6中取消了v4中的广播&#xff0c;新…