图论——spfa判负环
负环
图 G G G中存在一个回路,该回路边权之和为负数,称之为负环。
spfa求负环
方法1:统计每个点入队次数, 如果某个点入队n次, 说明存在负环。
证明:一个点入队n次,即被更新了n次。一个点每次被更新时所对应最短路的边数一定是递增的,也正因此该点被更新n次那么该点对应的的最短路长度一定大于等于n,即路径上点的个数至少为n+1。根据抽屉原理,路径中至少有一个顶点出现两次, 也就是路径中存在环路。 而算法保证只有距离减少才会更新, 所以环路权值之和为负数。
方法2:统计从起点到任意顶点最短路经过的边数, 若某点对应边数 c n t ≥ n cnt≥n cnt≥n, 则也说明负环。
方法2根据抽屉原理易证。
我们一般采用方法2才求负环。
acwing904.虫洞
spfa求负环模板题
#include <iostream>
#include <cstring>
using namespace std;
const int N = 510, M = 5210;
int h[N], w[M], e[M], ne[M], tot;
int dist[N];
int cnt[N];
bool st[N];
int q[N];
int t;
int n, m, k;
void add(int a, int b, int c)
{e[tot] = b, ne[tot] = h[a], w[tot] = c, h[a] = tot ++ ;
}
bool spfa()
{memset(dist, 0, sizeof dist);memset(st, 0, sizeof st);memset(cnt, 0, sizeof cnt);int hh = 0, tt = 0;for (int i = 1; i <= n; i ++ ){st[i] = 1;q[tt ++ ] = i;}while (hh != tt){int t = q[hh ++ ];if (hh == N) hh = 0;st[t] = 0;for (int i = h[t]; ~i; i = ne[i]){int j = e[i];if (dist[j] > dist[t] + w[i]){dist[j] = dist[t] + w[i];cnt[j] = cnt[t] + 1;if (cnt[j] == n) return true;if (st[j]) continue;st[j] = 1;q[tt ++ ] = j;if (tt == N) tt = 0;}}}return false;
}
int main()
{cin >> t;while (t -- ){cin >> n >> m >> k;tot = 0;memset(h, -1, sizeof h);while (m -- ){int a, b, c;cin >> a >> b >> c;add(a, b, c), add(b, a, c);}while (k -- ){int a, b, c;cin >> a >> b >> c;add(a, b, -c);}bool t = spfa();if (t) puts("YES");else puts("NO");}return 0;
}
acwing361.观光奶牛
本题要求我们求出环中存在的 ∑ f [ i ] ∑ t [ i ] \frac{\sum f[i]}{\sum t[i]} ∑t[i]∑f[i]的最大值,如果直接对问题进行求解是有难度的,考虑二分答案。首先易知,答案的范围在 [ 1 / 1000 , 1000 ] [1/1000, 1000] [1/1000,1000]之间,假设我们当前二分到的答案为 m i d mid mid,如果 a n s < m i d ans< mid ans<mid,我们可以去左半区间进行寻找,反之我们去右半区间寻找。
∑ f [ i ] ∑ t [ i ] > m i d \frac{\sum f[i]}{\sum t[i]}> mid ∑t[i]∑f[i]>mid
∑ f [ i ] > m i d ∗ ∑ t [ i ] \sum f[i]> mid*\sum t[i] ∑f[i]>mid∗∑t[i]
∑ f [ i ] − m i d ∗ ∑ t [ i ] > 0 \sum f[i]-mid*\sum t[i]> 0 ∑f[i]−mid∗∑t[i]>0
∑ ( f [ i ] − m i d ∗ t [ i ] ) > 0 \sum (f[i]-mid*t[i])> 0 ∑(f[i]−mid∗t[i])>0
∑ ( m i d ∗ t [ i ] − f [ i ] ) < 0 \sum (mid*t[i]-f[i])< 0 ∑(mid∗t[i]−f[i])<0
经过转换后,问题就等价于把图中边权换为 m i d ∗ t [ i ] − f [ i ] mid*t[i]-f[i] mid∗t[i]−f[i],然后判断图中是否存在负环,存在负环则说明图中存在 ∑ f [ i ] ∑ t [ i ] > m i d \frac{\sum f[i]}{\sum t[i]}>mid ∑t[i]∑f[i]>mid的环。
#include <iostream>
#include <cstring>
using namespace std;
const int N = 1010, M = 5010;
int h[N], e[M], ne[M], tot;
int wf[N], wt[M];
int q[N];
double dist[N];
int cnt[N];
bool st[N];
int n, m;
void add(int a, int b, int c)
{e[tot] = b, ne[tot] = h[a], wt[tot] = c, h[a] = tot ++ ;
}
bool check(double x)
{memset(dist, 0, sizeof dist);memset(st, 0, sizeof st);memset(cnt, 0, sizeof cnt);int hh = 0, tt = 0;for (int i = 1; i <= n; i ++ ){st[i] = 1;q[tt ++ ] = i;}while (hh != tt){int t = q[hh ++ ];if (hh == N) hh = 0;st[t] = 0;for (int i = h[t]; ~i; i = ne[i]){int j = e[i];double w = x * wt[i] - wf[t];if (dist[j] > dist[t] + w){dist[j] = dist[t] + w;cnt[j] = cnt[t] + 1;if (cnt[j] == n) return true;if (st[j]) continue;st[j] = 1;q[tt ++ ] = j;if (tt == N) tt = 0;}}}return false;
}
int main()
{cin >> n >> m;for (int i = 1; i <= n; i ++ )cin >> wf[i];memset(h, -1, sizeof h);for (int i = 1; i <= m; i ++ ){int a, b, c;cin >> a >> b >> c;add(a, b, c);}double l = 0, r = 1001;while (r - l > 1e-4){double mid = (l + r) / 2;if (check(mid)) l = mid;else r = mid;}printf("%.2lf", l);return 0;
}
acwing1165.单词环
我们第一感觉是把每一个单词看作一个节点,这样一来节点总数 n = 1 0 5 n=10^5 n=105,最坏情况是所有单词都可以互相进行匹配,这样一来边数 m = 1 0 5 ∗ 1 0 5 = 1 0 10 m=10^5*10^5=10^{10} m=105∗105=1010,考虑其他建图方式。
我们可以把每个单词看作一条边,这样一来边数 m = 1 0 5 m=10^5 m=105,每个单词开头结尾两个字母为节点,节点总数 n = 26 ∗ 26 = 676 n=26*26=676 n=26∗26=676。
本题要求我们求所有环的 ∑ w [ i ] ∑ 1 \frac{\sum w[i]}{\sum 1} ∑1∑w[i]最大值。和上题相同,二分答案,答案区间为 [ 1 / 1000 , 1000 ] [1/1000,1000] [1/1000,1000]。
∑ w [ i ] ∑ 1 > m i d \frac{\sum w[i]}{\sum 1}> mid ∑1∑w[i]>mid
∑ w [ i ] > m i d \sum w[i]> mid ∑w[i]>mid
∑ w [ i ] − m i d > 0 \sum w[i]-mid> 0 ∑w[i]−mid>0
∑ ( w [ i ] − m i d ) > 0 \sum (w[i]-mid)> 0 ∑(w[i]−mid)>0
∑ ( m i d − w [ i ] ) < 0 \sum (mid-w[i])< 0 ∑(mid−w[i])<0
经过转换后,问题就等价于把图中边权换为 m i d − w [ i ] mid-w[i] mid−w[i],然后判断图中是否存在负环,存在负环则说明图中存在 ∑ w [ i ] ∑ 1 > m i d \frac{\sum w[i]}{\sum 1}>mid ∑1∑w[i]>mid的环。
#include <iostream>
#include <cstring>
using namespace std;
const int N = 26 * 26 + 10, M = 100010;
int h[N], e[M], ne[M], w[M], tot;
double dist[N];
bool st[N];
int cnt[N];
int q[N];
char s[1010];
int n;
void add(int a, int b, int c)
{e[tot] = b, ne[tot] = h[a], w[tot] = c, h[a] = tot ++ ;
}
bool check(double mid)
{memset(st, 0, sizeof st);memset(dist, 0, sizeof dist);memset(cnt, 0, sizeof cnt);int hh = 0, tt = 0;for (int i = 0; i < 26 * 26; i ++ ){q[tt ++ ] = i;st[i] = 1;}int count = 0;while (hh != tt){int t = q[hh ++ ];st[t] = 0;if (hh == N) hh = 0;for (int i = h[t]; ~i; i = ne[i]){int j = e[i];double ww = mid - w[i];if (dist[j] > dist[t] + ww){dist[j] = dist[t] + ww;cnt[j] = cnt[t] + 1;if (++ count == 10000) return true;if (cnt[j] == N) return true;if (st[j]) continue;st[j] = 1;q[tt ++ ] = j;if (tt == N) tt = 0;}}}return false;
}
int main()
{while (cin >> n, n){memset(h, -1, sizeof h);tot = 0;for (int i = 1; i <= n; i ++ ){cin >> s;int len = strlen(s);if (len < 2) continue;int ll = (s[0] - 'a') * 26 + s[1] - 'a';int rr = (s[len - 2] - 'a') * 26 +s[len - 1] - 'a';add(ll, rr, len);}double l = 0, r = 1001;if (!check(0)) puts("No solution");else{while (r - l > 1e-4){double mid = (l + r) / 2;if (check(mid)) l = mid;else r = mid;}printf("%.2lf\n", r);}}return 0;
}
相关文章:
图论——spfa判负环
负环 图 G G G中存在一个回路,该回路边权之和为负数,称之为负环。 spfa求负环 方法1:统计每个点入队次数, 如果某个点入队n次, 说明存在负环。 证明:一个点入队n次,即被更新了n次。一个点每次被更新时所对应最短路的边数一定是…...
软件工程概论试题三
一、单选 1.需求确认主要检査五个方面的内容,其中那一项是为了保证文档中的需求不互相冲突(即不应该有相互矛盾的约束或者对同一个系统功能有不同的描述)。 A.现实性 B. 可验证性 C.一致性 D.正确性 E.完整性 正答:C 2.下列开发方法中,( )不…...

21.3-启动流程、编码风格(了解) 第21章-FreeRTOS项目实战--基础知识之新建任务、启动流程、编码风格、系统配置 文件组成和编码风格(了解)
21.3-启动流程、编码风格(了解) 启动流程 第一种启动流程(我们就使用这个): 在main函数中将硬件初始化、RTOS系统初始化,同时创建所有任务,再启动RTOS调度器。 第二种启动流程: 在main函数中将硬件初始化、RTOS系统初始化,只…...
未来无线技术的发展方向
未来无线技术的发展趋势呈现出多样化、融合化的特点,涵盖速度、覆盖范围、应用领域、频段利用、安全性等多个方面。这些趋势将深刻改变人们的生活和社会的运行方式。 传输速度提升:Wi-Fi 技术迭代加快,如 Wi-Fi7 理论峰值速率达 46Gbps&#…...
Qt5离线安装包无法下载问题解决办法
想在电脑里装一个Qt,但是直接报错。果然还是有解决办法滴。 qt download from your ip is not allowed Qt5安装包下载办法 方法一:简单直接,直接科学一下,不过违法行为咱不做,遵纪守法好公民(不过没办法阻…...

qt-C++笔记之QLine、QRect、QPainterPath、和自定义QGraphicsPathItem、QGraphicsRectItem的区别
qt-C笔记之QLine、QRect、QPainterPath、和自定义QGraphicsPathItem、QGraphicsRectItem的区别 code review! 参考笔记 1.qt-C笔记之重写QGraphicsItem的paint方法(自定义QGraphicsItem) 文章目录 qt-C笔记之QLine、QRect、QPainterPath、和自定义QGraphicsPathItem、QGraphic…...
doris:导入时实现数据转换
Doris 在数据导入时提供了强大的数据转换能力,可以简化部分数据处理流程,减少对额外 ETL 工具的依赖。主要支持以下四种转换方式: 列映射:将源数据列映射到目标表的不同列。 列变换:使用函数和表达式对源数据进行实时…...

新版231普通阿里滑块 自动化和逆向实现 分析
声明: 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 逆向过程 补环境逆向 部分补环境 …...
如何构建树状的思维棱镜认知框架
在思维与知识管理中,“树状思维棱镜”通常指一种层级式、可多维度展开和不断深入(下钻)的认知框架。它不仅仅是普通的树状结构(如传统思维导图),更强调“棱镜”所体现的多视角、多维度切换与综合分析的能力…...

openRv1126 AI算法部署实战之——ONNX模型部署实战
在RV1126开发板上部署ONNX算法,实时目标检测RTSP传输。视频演示地址 rv1126 yolov5 实时目标检测 rtsp传输_哔哩哔哩_bilibili 一、准备工作 1.从官网下载YOLOv5-v7.0工程(YOLOv5的第7个版本) 手动在线下载: Releases ultraly…...
Vue 组件开发:构建高效可复用的前端界面要素
1 引言 在现代 Web 开发中,构建高效且可复用的前端界面要素是提升开发效率和用户体验的关键。Vue.js 作为一种轻量级且功能强大的前端框架,提供了丰富的工具和机制,帮助开发者快速构建高质量的应用程序。通过合理设计和封装 Vue 组件,我们可以实现组件的高效复用,提高开发…...
Vue.js组件开发-实现全屏平滑移动、自适应图片全屏滑动切换
使用Vue实现全屏平滑移动、自适应图片全屏滑动切换的功能。使用Vue 3和Vue Router,并结合一些CSS样式来完成这个效果。 步骤 创建Vue项目:使用Vue CLI创建一个新的Vue项目。准备图片:将需要展示的图片放在项目的public目录下。创建组件&…...
水果实体店品牌数字化:RWA + 智能体落地方案
一、方案背景 随着数字化技术的迅猛发展,实体零售行业正面临前所未有的挑战与机遇。传统的零售模式难以满足消费者对个性化、便捷化、智能化的需求,尤其是在水果等生鲜商品领域,如何通过技术手段提升运营效率、增强顾客体验、拓宽盈利模式&a…...
DeepSeek模型:开启人工智能的新篇章
DeepSeek模型:开启人工智能的新篇章 在当今快速发展的技术浪潮中,人工智能(AI)已经成为了推动社会进步和创新的核心力量之一。而DeepSeek模型,作为AI领域的一颗璀璨明珠,正以其强大的功能和灵活的用法&…...
Kubernetes 环境中的自动化运维实战指南
Kubernetes 作为容器编排领域的领导者,已经成为云原生应用的核心基础设施。然而,随着集群规模的扩大和应用的复杂化,手动运维 Kubernetes 集群变得愈发困难。自动化运维成为提升效率、保障系统稳定性的关键。本文将详细介绍如何在 Kubernetes 环境中实施自动化运维,涵盖工具…...

深入解析 C++17 中的 std::not_fn
文章目录 1. std::not_fn 的定义与目的2. 基本用法2.1 基本示例2.2 使用 Lambda 表达式2.3 与其他函数适配器的比较3. 在标准库中的应用3.1 结合标准库算法使用3.1.1 std::find_if 中的应用3.1.2 std::remove_if 中的应用3.1.3 其他标准库算法中的应用4. 高级技巧与最佳实践4.1…...

unity实现回旋镖函数
最近学习unity2D,想实现一个回旋镖武器,发出后就可以在角色周围回旋。 一、目标 1.不是一次性的,扔出去、返回、没有了;而是扔出去,返回到角色后方相同距离,再次返回;再次返回,永远…...

想品客老师的第九天:原型和继承
原型与继承前置看这里 原型 原型都了解了,但是不是所有对象都有对象原型 let obj1 {}console.log(obj1)let obj2 Object.create(null, {name: {value: 荷叶饭}})console.log(obj2) obj2为什么没有对象原型?obj2是完全的数据字典对象,没有…...
力扣【416. 分割等和子集】详细Java题解(背包问题)
首先我们可以求出数组和,当我们找到一个子集中元素的和为数组和的一半时,该就说明可以分割等和子集。 对于该问题我们可以转换成背包问题,求 数组里的元素 装入 数组和的一半大小的背包 能取得的最大值。 然后注意可以剪枝的地方。 代码&…...

2025年AI手机集中上市,三星Galaxy S25系列上市
2025年被认为是AI手机集中爆发的一年,各大厂商都会推出搭载人工智能的智能手机。三星Galaxy S25系列全球上市了。 三星Galaxy S25系列包含S25、S25和S25 Ultra三款机型,起售价为800美元(约合人民币5800元)。全系搭载骁龙8 Elite芯…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...

select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...

Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...

中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...

代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
Bean 作用域有哪些?如何答出技术深度?
导语: Spring 面试绕不开 Bean 的作用域问题,这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开,结合典型面试题及实战场景,帮你厘清重点,打破模板式回答,…...