首页 > 其他分享 >bfs+双端队列

bfs+双端队列

时间:2024-08-26 22:53:11浏览次数:13  
标签:队列 双端 边权 bfs int 算法

算法介绍

\(bfs+\)双端队列是一种单源最短路算法,适用于边权为 \(0\) 或 \(1\) 的图中。时间复杂度为 \(O(n)\) 。

算法原理分析

算法的整体框架与普通 \(bfs\) 求最短路类似,只是根据边权做了分类讨论,如果边权为 \(1\),则将邻居节点压到队列尾部,反之,压到队列首部。当每个节点第一次出队时,当前距离就是最短距离。

例题:[P4667 [BalticOI 2011 Day1] Switch the Lamp On 电路维修]([P4667 BalticOI 2011 Day1] Switch the Lamp On 电路维修 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn))

题目大意:本题可以建模成最短路问题,将转动次数看作边权。题目的时间限制为 \(150ms\),而节点数为 \((n+1)*(m+1) \leq 251001\)。因此,必须使用时间复杂度为 \(O(n)\)的算法来解决。

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 5e2 + 5, P = 13331;
struct node
{
    int x, y, dis;
};
int mp[N][N];
int n, m, dis[N][N];
int dx[4] = {-1, -1, 1, 1}, dy[4] = {-1, 1, -1, 1};
int cd[4][2] = {{-1, -1}, {-1, 0}, {0, -1}, {0, 0}};
int key[4] = {2, 1, 1, 2};
deque<node> dq;
int read_ch()
{
    char c;
    while ((c = getchar()) != '/' && c != '\\')
        ;
    return c == '/' ? 1 : 2;
}
void solve()
{
    int T = 1;
    // cin>>T;
    while (T--)
    {
        cin >> n >> m;
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= m; j++)
            {
                mp[i][j] = read_ch();
            }
        }
        memset(dis, 0x3f, sizeof(dis));
        dq.push_back({1, 1, 0});
        dis[1][1] = 0;
        while (!dq.empty())
        {
            int x = dq.front().x, y = dq.front().y, d = dq.front().dis;
            dq.pop_front();
            for (int i = 0; i < 4; i++)
            {
                int nx = x + dx[i], ny = y + dy[i];
                int w = mp[x + cd[i][0]][y + cd[i][1]] != key[i];
                if (nx && ny && nx <= n + 1 && ny <= m + 1 && d + w < dis[nx][ny])
                {
                    dis[nx][ny] = d + w;
                    if (w == 0)
                        dq.push_front({nx, ny, dis[nx][ny]});
                    else
                        dq.push_back({nx, ny, dis[nx][ny]});
                    if (nx == n + 1 && ny == m + 1)
                        break;
                }
            }
        }
        if (dis[n + 1][m + 1] == 0x3f3f3f3f)
            cout << "NO SOLUTION";
        else
            cout << dis[n + 1][m + 1];
    }
}
int main()
{
    solve();
    return 0;
}

标签:队列,双端,边权,bfs,int,算法
From: https://www.cnblogs.com/zc-study-xcu/p/18381689

相关文章

  • 代码随想录训练营day29|134.加油站,135. 分发糖果,860.柠檬水找零,406.根据身高重建队列
    加油站想法:暴力遍历?好吧第一遍写的时候读错题意了,以为是比较gas[i]与cost[i+1]的值,shit。intsum1=0,sum2=0;for(intg:gas)sum1+=g;for(intc:cost)sum2+=c;if(sum1<sum2)return-1;//如果gas没cost多intyouliang=0;intn=gas.size()......
  • Luogu P7250 BalticOI 山峰 题解 [ 蓝 ] [ 模拟 ] [ 并查集 ] [ BFS ]
    LuoguP7250BalticOI山峰。一道大模拟,很暴力,也很难写。建议紫或蓝,标签为模拟、广度优先搜索、并查集。思路首先观察到答案取决于路线上的最低点,所以我们可以把所有点的高度丢进一个桶里,从大到小枚举,尝试更新答案。这应该是个挺经典的trick了。感性理解可以看作所有山都先......
  • 图论:图的遍历(DFS vs. BFS)
    文章目录引言基本概念无向图示例绘制图形深度优先搜索(DFS)基本概念可视化DFS过程深度优先搜索(DFS)DFS应用场景广度优先搜索(BFS)基本概念可视化BFS过程广度优先搜索(BFS)应用场景DFSvs.BFS基本概念对比性能对比场景分析**总结对比**社交网络图遍历使用DFS使用BFS......
  • 谷粒商城实战笔记-259-商城业务-消息队列-可靠投递-发送端确认
    文章目录一,确认机制简介二,ConfirmCallback三,returnCallback事务消息的问题一,确认机制简介RabbitMQ的消息确认机制主要包括以下几种:发布者确认(PublisherConfirm):在发布者和代理之间建立一个确认协议。当发布者发送一条消息到代理时,代理会返回一个确认信息给发布者......
  • 谷粒商城实战笔记-260-商城业务-消息队列-可靠投递-消费端确认
    文章目录一,Ack消息确认机制简介1,简介2,两个常用的Api二,消费者端消息确认实战三,RabbitMQ可靠性保障总结1,生产者2,消费者一,Ack消息确认机制简介消费者端的确认机制(ACK/NACK)是RabbitMQ中一种重要的特性,它允许消费者告知Broker它们是否成功处理了接收到的......
  • springboot整合rabbitmq实现延迟队列
     一、rabbitmq安装使用dicker进行安装,点击查看 二、引入maven依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId><version>2.5.15</version></dependency>......
  • 消息队列-RabbitMQ学习笔记(一)
    1.什么是消息队列消息队列(MessageQueue,简称MQ)是一种用于在应用程序之间传递消息的技术,通常在分布式系统中使用。它提供了一种异步通信机制,使得应用程序可以通过发送和接收消息来进行数据交换。消息队列可以用来存储消息,这就涉及到消息队列的三个关键字:存储、消息、队列......
  • linux下试验中间件canal的example示例-binlog日志的实时获取显示以及阿里巴巴中间件ca
    一、linux下试验中间件canal的example示例-binlog日志的实时获取显示    今天重装mysql后,进行了canal的再次试验,原来用的mysql5.7,今天重装直接换了5.6算了。反正测试服务器的mysql也不常用。canal启动后日志显示examplepreparetofindstartpositionjustshowmaste......
  • apr库编译及队列使用笔记
    操作系统:CentOS7.9_x64apr库版本:apr-1.7.4&apr-util-1.6.3gcc版本:4.8.5队列功能在C++或Python等脚本语言里面,是很容易就可以使用的,但C语言里面,标准库里面没有。在使用C语言开发新应用时,就会遇到这个问题。阅读FreeSWITCH源码,发现使用的是apr库,一个强大的开发库,提供了一套......
  • 怎样解决线上消息队列积压问题
    目录引言消息积压的原因解决方案Kafka消息积压引言提到消息队列,最常问到的问题就是消息积压,真实线上环境该怎么解决消息积压的问题?真实情况并不是网上说的把积压的消息投递到一个新Topic中,然后慢慢消费。这样做,成本太高、流程复杂、操作麻烦,而且还是一次性操作,不可持续,下次再出......