NO.95十六届蓝桥杯备战|图论基础-单源最短路|负环|BF判断负环|SPFA判断负环|邮递员送信|采购特价产品|拉近距离|最短路计数(C++)

P3385 【模板】负环 - 洛谷

如果图中存在负环,那么有可能不存在最短路。
![[Pasted image 20250416144354.png]]

BF算法判断负环
  • 执⾏n轮松弛操作,如果第n轮还存在松弛操作,那么就有负环。
#include <bits/stdc++.h>
using namespace std;const int N = 2e3 + 10, M = 3e3 + 10;int n, m;
int pos;
struct node
{int u, v, w;
}e[M * 2];int dist[N];bool bf()
{//初始化memset(dist, 0x3f, sizeof dist);dist[1] = 0;bool flg;for (int i = 1; i <= n; i++){flg = false;for (int j = 1; j <= pos; j++){int u = e[j].u, v = e[j].v, w = e[j].w;if (dist[u] == 0x3f3f3f3f) continue;if (dist[u] + w < dist[v]){flg = true;dist[v] = dist[u] + w;}}if (flg == false) return flg;}return flg;
}int main()
{ios::sync_with_stdio(false);cin.tie(0);int T; cin >> T;while (T--){cin >> n >> m;pos = 0;for (int i = 1; i <= m; i++){int u, v, w; cin >> u >> v >> w;pos++;e[pos].u = u, e[pos].v = v, e[pos].w = w;if (w >= 0){pos++;e[pos].u = v, e[pos].v = u, e[pos].w = w;}}if (bf()) cout << "YES" << endl;else cout << "NO" << endl;}return 0;
}
spfa算法判断负环
  • 维护⼀个 cnt 数组记录从起点到该点所经过的边数,如果 cnt[i] >= n ,说明有负环
#include <bits/stdc++.h>
using namespace std;typedef pair<int, int> PII;const int N = 2e3 + 10, M = 3e3 + 10;int n, m;
vector<PII> edges[N];int dist[N];
bool st[N]; //标记在队列中
int cnt[N];bool spfa()
{//初始化memset(dist, 0x3f, sizeof dist);memset(st, 0, sizeof st);memset(cnt, 0, sizeof cnt);queue<int> q;q.push(1);dist[1] = 0;st[1] = true;while (q.size()){auto u = q.front(); q.pop();st[u] = false;for (auto& t : edges[u]){int v = t.first, w = t.second;if (dist[u] + w < dist[v]){dist[v] = dist[u] + w;cnt[v] = cnt[u] + 1;if (cnt[v] >= n) return true;if (!st[v]){q.push(v);st[v] = true;}}}}return false;
}int main()
{ios::sync_with_stdio(false);cin.tie(0);int T; cin >> T;while (T--){cin >> n >> m;for (int i = 1; i <= n; i++) edges[i].clear();for (int i = 1; i <= m; i++){int u, v, w; cin >> u >> v >> w;edges[u].push_back({v, w});if (w >= 0) edges[v].push_back({u, w});}if (spfa()) cout << "YES" << endl;else cout << "NO" << endl;}return 0;
}
常规版-dijkstra堆优化-dijkstrabellman‒ford算法spfa算法
算法思想贪⼼
• 每次拿出还未确定 最短路的点中,距离起点最近的点;
• 打上标记之后,更新出边所连点的最短路。
使⽤堆优化找点操作:
• 把还未确定最短路的点扔到堆中,⽤堆快速找出距离起点最近的点。
暴⼒松弛:
• 执⾏n-1轮松弛操作;
• 每次都扫描所有的边,看看能否松弛。
使⽤队列优化bf算
法:
• 只有上⼀轮被松弛的点,下⼀轮才有可能松弛。
负边权失效失效可⾏可⾏
负环失效失效可以判断负环:
• 执⾏n轮操作,判断是否松弛
可以判断负环:
• 创建cnt数组,
标记从起点到该
点的边数
时间复杂度O(n2)O(mlog m)O(nm)O(km) ~O(nm)

其实还有两个单源最短路算法,那就是普通bfs以及01bfs:

  • 普通bfs只能处理边权全部相同且⾮负的最短路;
  • 01bfs只能解决边权要么为0,要么为1的情况
P1629 邮递员送信 - 洛谷

从起点找别的点的最短距离很简单,直接跑各种最短路算法均可。
但是从别的点回到起点的最短路,如果直接求时间复杂度巨⾼。思考⼀件事:

  • 假设从某⼀点z,到达起点的最短路径为:z->y->x->s;
  • 那么反过来就是s->x->y->z的最短路径。
    因此,仅需对原图的所有图建⽴⼀个"反图",然后跑⼀遍最短路即可。这就是建"反图"的技巧
#include <bits/stdc++.h>
using namespace std;const int N = 1e3 + 10;int n, m;
int e[N][N];int dist[N];
bool st[N];void dijkstra()
{memset(dist, 0x3f, sizeof dist);memset(st, 0, sizeof st);dist[1] = 0;for (int i = 1; i <= n; i++){int a = 0;for (int j = 1; j <= n; j++)if (!st[j] && dist[j] < dist[a])a = j;st[a] = true;for (int b = 1; b <= n; b++){int c = e[a][b];if (dist[a] + c < dist[b]){dist[b] = dist[a] + c;}}}
}int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> n >> m;memset(e, 0x3f, sizeof e);for (int i = 1; i <= m; i++){int a, b, c; cin >> a >> b >> c;e[a][b] = min(e[a][b], c);}dijkstra();int ret = 0;for (int i = 1; i <= n; i++) ret += dist[i];//反图for (int i = 1; i <= n; i++)for (int j = i+1; j <= n; j++)swap(e[i][j], e[j][i]);dijkstra();for (int i = 1; i <= n; i++) ret += dist[i];cout << ret << endl;return 0;
}
P1744 采购特价商品 - 洛谷

看数据范围,所有的最短路算法均可解决,这⾥使⽤BF算法。
⽆需建图,只⽤把所有的边存下来。注意是⽆向边,所以要存两次,空间也要开两倍。
在所有边上做⼀次bf算法,输出结果即可

#include <bits/stdc++.h>
using namespace std;const int N = 110, M = 1010;int n, m, s, t;
double x[N], y[N];struct node
{int a, b;double c;
}e[M];double calc(int i, int j)
{double dx = x[i] - x[j];double dy = y[i] - y[j];return sqrt(dx * dx + dy * dy);
}double dist[N];void bf()
{for (int i = 1; i <= n; i++) dist[i] = 1e10;dist[s] = 0;for (int i = 1; i < n; i++){for (int j = 1; j <= m; j++){int a = e[j].a, b = e[j].b;double c = e[j].c;if (dist[a] + c < dist[b]){dist[b] = dist[a] + c;}if (dist[b] + c < dist[a]){dist[a] = dist[b] + c;}}}
}int main()
{cin >> n;for (int i = 1; i <= n; i++) cin >> x[i] >> y[i];cin >> m;for (int i = 1; i <= m; i++){int a, b; cin >> a >> b;e[i].a = a; e[i].b = b; e[i].c = calc(a, b);}cin >> s >> t;bf();printf("%.2lf\n", dist[t]);return 0;
}
P2136 拉近距离 - 洛谷

bf算法判断负环即可。但要注意⼀下细节:

  1. 题⽬中给的是距离w是能缩⼩的数,因此存边的时候,应该存成相反数;
  2. 爱情是双向奔赴的,我们要在1->n和n->1两种情况⾥⾯选择最⼩值
#include <bits/stdc++.h>
using namespace std;const int N = 1e3 + 10, M = 1e4 + 10;int n, m;
struct node
{int a, b, c;
}e[M];int dist[N];bool bf(int s)
{memset(dist, 0x3f, sizeof dist);dist[s] = 0;bool flg;for (int i = 1; i <= n; i++){flg = false;for (int j = 1; j <= m; j++){int a = e[j].a, b = e[j].b, c = e[j].c;if (dist[a] + c < dist[b]){flg = true;dist[b] = dist[a] + c;}}if (flg == false) return flg;}return flg;
}int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> n >> m;for (int i = 1; i <= m; i++){cin >> e[i].a >> e[i].b >> e[i].c;e[i].c = -e[i].c;}int ret;bool st = bf(1);if (st){cout << "Forever love" << endl;return 0;}ret = dist[n];st = bf(n);if (st){cout << "Forever love" << endl;return 0;}cout << min(ret, dist[1]) << endl;return 0;
}
P1144 最短路计数 - 洛谷

解法⼀:bfs+动态规划

  • 因为边权全都相等,所以可以⽤bfs找出最短路;
  • 在bfs找最短路的过程中,更新最短路的条数。
    动态规划:
  1. 状态表⽰:设 f[i] 表⽰从起点⾛到 i 点的最短路的条数。
  2. 状态转移⽅程: f[i] += f[prev]
    其中 prev 表⽰ i 点的所有前驱,但是要注意是通过最短路过来的前驱。
  3. 填表顺序:按照bfs的顺序填表。
    解法⼆:dijkstra算法+动态规划
    这种解法更通⽤,因为即使边权不相等,也可以⽤dj算法
#include <bits/stdc++.h>
using namespace std;typedef pair<int, int> PII;
const int N = 1e6 + 10, M = 2e6 + 10, MOD = 100003;int n, m;
vector<int> edges[N];int dist[N];
bool st[N];
int f[N];void bfs()
{memset(dist, 0x3f, sizeof dist);queue<int> q;q.push(1);dist[1] = 0;f[1] = 1;while (q.size()){auto a = q.front(); q.pop();for (auto b : edges[a]){if (dist[a] + 1 < dist[b]){dist[b] = dist[a] + 1;f[b] = f[a];q.push(b);}else if (dist[a] + 1 == dist[b]){f[b] = (f[b] + f[a]) % MOD;}}}
}int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> n >> m;for (int i = 1; i <= m; i++){int a, b; cin >> a >> b;edges[a].push_back(b);edges[b].push_back(a);}bfs();for (int i = 1; i <= n; i++) cout << f[i] << endl;return 0;
}
#include <bits/stdc++.h>
using namespace std;typedef pair<int, int> PII;
const int N = 1e6 + 10, M = 2e6 + 10, MOD = 100003;int n, m;
vector<int> edges[N];int dist[N];
bool st[N];
int f[N];void dijkstra()
{memset(dist, 0x3f, sizeof dist);priority_queue<PII, vector<PII>, greater<PII>> heap;heap.push({0, 1});dist[1] = 0;f[1] = 1;while (heap.size()){auto t = heap.top(); heap.pop();int a = t.second;if (st[a]) continue;st[a] = true;for (auto b : edges[a]){if (dist[a] + 1 < dist[b]){dist[b] = dist[a] + 1;f[b] = f[a];heap.push({dist[b], b});}else if (dist[a] + 1 == dist[b]){f[b] = (f[a] + f[b]) % MOD;}}}
}int main()
{ios::sync_with_stdio(false);cin.tie(0);cin >> n >> m;for (int i = 1; i <= m; i++){int a, b; cin >> a >> b;edges[a].push_back(b);edges[b].push_back(a);}dijkstra();for (int i = 1; i <= n; i++) cout << f[i] << endl;return 0;
}

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

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

相关文章

K8s pod 应用

/** 个人学习笔记&#xff0c;如有问题欢迎交流&#xff0c;文章编排和格式等问题见谅&#xff01; */ &#xff08;1&#xff09;编写 pod.yaml 文件 pod 是 kubernetes 中最小的编排单位&#xff0c;一个 pod 里包含一个或多个容器。 apiVersion: v1 # 指定api版本 kind…

Oracle创建触发器实例

一 创建DML 触发器 DML触发器基本要点&#xff1a; 触发时机&#xff1a;指定触发器的触发时间。如果指定为BEFORE&#xff0c;则表示在执行DML操作之前触发&#xff0c;以便防止某些错误操作发生或实现某些业务规则&#xff1b;如果指定为AFTER&#xff0c;则表示在执行DML操作…

Filename too long 错误

Filename too long 错误表明文件名超出了文件系统或版本控制系统允许的最大长度。 可能的原因 文件系统限制 不同的文件系统对文件名长度有不同的限制。例如&#xff0c;FAT32 文件名最长为 255 个字符&#xff0c;而 NTFS 虽然支持较长的文件名&#xff0c;但在某些情况下也…

网络不可达network unreachable问题解决过程

问题&#xff1a;访问一个环境中的路由器172.16.1.1&#xff0c;发现ssh无法访问&#xff0c;ping发现回网络不可达 C:\Windows\System32>ping 172.16.1.1 正在 Ping 172.16.1.1 具有 32 字节的数据: 来自 172.16.81.1 的回复: 无法访问目标网。 来自 172.16.81.1 的回复:…

Python设计模式:备忘录模式

1. 什么是备忘录模式&#xff1f; 备忘录模式是一种行为设计模式&#xff0c;它允许在不暴露对象内部状态的情况下&#xff0c;保存和恢复对象的状态。备忘录模式的核心思想是将对象的状态保存到一个备忘录对象中&#xff0c;以便在需要时可以恢复到之前的状态。这种模式通常用…

Python基础语法3

目录 1、函数 1.1、语法格式 1.2、函数返回值 1.3、变量作用域 1.4、执行过程 1.5、链式调用 1.6、嵌套调用 1.7、函数递归 1.8、参数默认值 1.9、关键字参数 2、列表 2.1、创建列表 2.2、下标访问 2.3、切片操作 2.4、遍历列表元素 2.5、新增元素 2.6、查找元…

JavaEE学习笔记(第二课)

1、好用的AI代码工具cursor 2、Java框架&#xff1a;Spring(高级框架)、Servelt、Struts、EJB 3、Spring有两层含义&#xff1a; ①Spring Framework&#xff08;原始框架&#xff09; ②Spring家族 4、Spring Boot(为了使Spring简化) 5、创建Spring Boot 项目 ① ② ③…

基于Flask与Ngrok实现Pycharm本地项目公网访问:从零部署

目录 概要 1. 环境与前置条件 2. 安装与配置 Flask 2.1 创建虚拟环境 2.2 安装 Flask 3. 安装与配置 Ngrok 3.1 下载 Ngrok 3.2 注册并获取 Authtoken 4. 在 PyCharm 中创建 Flask 项目 5. 运行本地 Flask 服务 6. 启动 Ngrok 隧道并获取公网地址 7. 完整示例代码汇…

Ragflow、Dify、FastGPT、COZE核心差异对比与Ragflow的深度文档理解能力​​和​​全流程优化设计

一、Ragflow、Dify、FastGPT、COZE核心差异对比 以下从核心功能、目标用户、技术特性等维度对比四款工具的核心差异&#xff1a; 核心功能定位 • Ragflow&#xff1a;专注于深度文档理解的RAG引擎&#xff0c;擅长处理复杂格式&#xff08;PDF、扫描件、表格等&#xff09;的…

LeetCode[232]用栈实现队列

思路&#xff1a; 一道很简单的题&#xff0c;就是栈是先进后出&#xff0c;队列是先进先出&#xff0c;用两个栈底相互对着&#xff0c;这样一个队列就产生了&#xff0c;右栈为空的情况&#xff0c;左栈栈底就是队首元素&#xff0c;所以我们需要将左栈全部压入右栈&#xff…

postman 删除注销账号

一、删除账号 1.右上角找到 头像&#xff0c;view profile https://123456-6586950.postman.co/settings/me/account 二、找回账号 1.查看日志所在位置 三、postman更新后只剩下history 在 Postman 中&#xff0c;如果你发现更新后只剩下 History&#xff08;历史记录&…

微服务相比传统服务的优势

这是一道面试题&#xff0c;咱们先来分析这道题考察的是什么。 如果分析面试官主要考察以下几个方面&#xff1a; 技术理解深度 你是否清楚微服务架构&#xff08;Microservices&#xff09;和传统单体架构&#xff08;Monolithic&#xff09;的本质区别。能否从设计理念、技术…

【KWDB 创作者计划】_深度学习篇---向量指令集

文章目录 前言一、加速原理数据级并行(DLP)计算密度提升减少指令开销内存带宽优化隐藏内存延迟二、关键实现技术1. 手动向量化(Intrinsics)优势挑战2. 编译器自动向量化限制3. BLAS/LAPACK库优化4. 框架级优化三、典型应用场景矩阵运算卷积优化归一化/激活函数嵌入层(Embe…

跳跃游戏(每日一题-中等)

题解&#xff1a;定义一个变量&#xff0c;用来存储可以到达的最远位置。初始化为0。 然后对数组进行遍历&#xff0c;遍历开始的时候&#xff0c;先判断当前这个位置和最远位置谁大&#xff0c;如果最远位置比较大&#xff0c;那么就说明当前这个位置也能达到&#xff0c;就看…

第七篇:linux之基本权限、进程管理、系统服务

第七篇&#xff1a;linux之基本权限、进程管理、系统服务 文章目录 第七篇&#xff1a;linux之基本权限、进程管理、系统服务一、基本权限1、什么是权限&#xff1f;2、为什么要有权限&#xff1f;3、权限与用户之间的关系&#xff1f;4、权限对应的数字含义5、使用chmod设定权…

音视频小白系统入门课-2

本系列笔记为博主学习李超老师课程的课堂笔记&#xff0c;仅供参阅 往期课程笔记传送门&#xff1a; 音视频小白系统入门笔记-0音视频小白系统入门笔记-1 课程实践代码仓库&#xff1a;传送门 音视频编解码 可以通过ffmpeg -f avfoundation -list_devices true -i "&…

外卖“三国杀”开新局,饿了么已手握AI牌

【潮汐商业评论/原创】 01 新战役&#xff0c;新变量 外卖行业&#xff0c;又迎来了新一轮战役。 前有京东宣布斥资百亿进军外卖市场&#xff0c;后有美团宣布发布即时零售品牌“美团闪购”。双方在隔空秀肌肉、彰显自身实力的同时&#xff0c;行业巨头围绕本地生活服务的攻…

HAProxy 和 Keepalived 区别

HAProxy 和 Keepalived 是在构建高可用和可扩展Web服务时常用的两个开源软件&#xff0c;但它们的核心功能和目的有显著区别。 简单来说&#xff1a; HAProxy: 主要是一个 负载均衡器 (Load Balancer) 和 反向代理 (Reverse Proxy)。它负责将客户端的请求智能地分发到后端的多…

YOLO算法的革命性升级:深度解析Repulsion损失函数在目标检测中的创新应用

## 一、目标检测的痛点与YOLO的局限性 在自动驾驶、智能监控等复杂场景中,目标检测算法常面临致命挑战——遮挡问题。当多个物体相互遮挡时,传统检测器容易出现漏检、误检现象,YOLO系列算法尽管在速度与精度上表现优异,但在处理密集遮挡目标时仍存在明显短板。 ### 1.1 遮…

第一篇:Django简介

第一篇&#xff1a;Django简介 文章目录 第一篇&#xff1a;Django简介一、纯手写一个简易版的web框架1、软件开发架构2、HTTP协议3、简易的socket服务端4、wsgiref模块5、动静态网页6、后端获取当前时间展示到html页面上7、字典数据传给html文件8、数据从数据库中获取的展示到…