算法学习笔记(差分约束系统)

前置:spfa

从例题入手:

【模板】差分约束系统 | StarryCoding

题目描述

给定 n n n未知量和一个大小为 m m m的不等式(或等式)组,请你判断这个不等式(或等式)组是否有解。

1 1 1 i i i j j j z z z:表示 x i ≤ x j + z x_i \leq x_j + z xixj+z

2 2 2 i i i j j j z z z:表示 x i ≥ x j + z x_i \geq x_j + z xixj+z

3 3 3 i i i j j j:表示 x i = y j x_i = y_j xi=yj

若存在解,输出 Y E S YES YES

若不存在解,输出 N O NO NO

输入描述

第一行一个整数 T T T表示样例个数。 ( 1 ≤ T ≤ 1000 ) (1 \leq T \leq 1000) (1T1000)

对于每组样例:

第一行两个整数 n , m n,m n,m ( 2 ≤ n ≤ 5 × 1 0 3 , 1 ≤ m ≤ 5 × 1 0 3 ) (2 \leq n \leq 5 \times 10^3,1 \leq m \leq 5 \times 10^3) (2n5×103,1m5×103)

接下来 m m m行,每行一个不等式组。 ( 1 ≤ i , j ≤ n , 1 ≤ z ≤ 1 0 7 ) (1 \leq i,j \leq n,1 \leq z \leq 10^7) (1i,jn,1z107)

数据保证 ∑ n ≤ 5 × 1 0 3 , ∑ m ≤ 1 0 4 \sum n \leq 5 \times 10^3, \sum m \leq 10^4 n5×103,m104

输出描述

对于每组样例,第一行输出 Y E S YES YES N O NO NO

输入样例

23 3
1 1 2 3
1 1 3 3
2 1 3 43 3
1 1 2 3
1 1 3 3
2 1 3 3

输出样例

NO
YES

在我们的 s p f a spfa spfa中,当 d [ y ] > d [ x ] + w d[y] > d[x] + w d[y]>d[x]+w时,我们就会更新 d [ y ] d[y] d[y],换句话说,若存在一条边连接着点 x x x y y y,则 d [ y ] < = d [ x ] + w d[y] <= d[x] + w d[y]<=d[x]+w恒成立。而这个不等式就相当于题目中第一个不等式 x i ≤ x j + z x_i \leq x_j + z xixj+z,这也就是差分约束的原理。

所以,对于 x i ≤ x j + z x_i \leq x_j + z xixj+z,可以假定有一条权值为 z z z的边从点 j j j出发指向 i i i

那具体如何判断所给不等式组是否有解?可以拟定一个虚拟源点 0 0 0,用边权为 0 0 0的边连到所有节点。然后从这个虚拟源点出发跑一遍最短路,若出现负环,则不等式组无解,因为出现负环时, 0 0 0 i i i的距离比 0 0 0 j j j的距离更远,用公式来讲就是 d [ i ] > d [ j ] + z d[i] > d[j] + z d[i]>d[j]+z x i > x j + z x_i > x_j + z xi>xj+z,不符合题意。

对于第二个不等式 x i ≥ x j + z x_i \geq x_j + z xixj+z则变形为, x j ≤ x i − z x_j \leq x_i - z xjxiz

对于第三个式子 x i = y j x_i = y_j xi=yj,则在 x x x y y y之间建立一个边权为 0 0 0的双向边。

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 9;
using ll = long long;
const ll inf = 2e18;struct Edge
{int x;ll w;
};int n, m;
vector<Edge> g[N];
ll d[N];bool spfa(int st)
{//两行初始化,不要忘记for(int i = 1; i <= n; ++i) d[i] = inf;d[st] = 0;queue<int> q;       //队列存储需要更新的点bitset<N> inq;      //inq[i]表示第i个点在不在队列中q.push(st);vector<int> cnt(n + 1);     //计数while(q.size())     {int x = q.front(); q.pop(); inq[x] = false;for(auto [y, w] : g[x])         //更新所有边{if(d[y] > d[x] + w)         //如果能被更新,更新且入队{if(++ cnt[y] >= n) return true;d[y] = d[x] + w;if(!inq[y]){q.push(y);inq[y] = true;}}}}return false;
}void solve()
{cin >> n >> m;for(int i = 0; i <= n; ++i) g[i].clear();for(int i = 1; i <= m; ++i){int op, x, y; cin >> op >> x >> y;if(op == 1){ll w; cin >> w;g[y].push_back({x, w});}if(op == 2){ll w; cin >> w;g[x].push_back({y, -w});}if(op == 3){g[y].push_back({x, 0});g[x].push_back({y, 0});}}for(int i = 1; i <= n; ++i) g[0].push_back({i, 0});if(spfa(0)) cout << "NO" << '\n';else cout << "YES" << '\n';
}int main()
{ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int _; cin >> _;while(_--) solve();return 0;
}

最后因为不等式组的解不唯一,输出时挑一个满足题意的解,只需要将距离数组 d d d输出即可。

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

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

相关文章

【Linux 命令操作】如何在 Linux 中使用多行注释呢?

文章目录 1. 给代码进行多行注释2. 给代码取消多行注释 1. 给代码进行多行注释 &#x1f427;① 首先用 vim 打开代码&#xff0c;按 Esc进入命令模式(Normal mode)&#xff1b; &#x1f427;② 然后按住 ctrl v 进入列模式&#xff1b; &#x1f427;③ 再通过按 h(左)、j(…

Yarn:下一代JavaScript包管理器的安装与实战指南

当然&#xff0c;让我们深入探讨Yarn——一个高效、可靠的JavaScript包管理器&#xff0c;它为前端开发带来了新的速度和便利。Yarn由Facebook、Google、Exponent和Tilde公司共同推出&#xff0c;旨在解决npm&#xff08;Node.js包管理器&#xff09;存在的问题&#xff0c;如依…

19.删除链表的倒数第n个结点

刷算法题&#xff1a; 第一遍&#xff1a;1.看5分钟&#xff0c;没思路看题解 2.通过题解改进自己的解法&#xff0c;并且要写每行的注释以及自己的思路。 3.思考自己做到了题解的哪一步&#xff0c;下次怎么才能做对(总结方法) 4.整理到自己的自媒体平台。 5.再刷重复的类…

python元组

创建元组 元组的创建使用小括号&#xff08;&#xff09; 创建空元组&#xff1a;tuple&#xff08;&#xff09; 可以使用tuple()函数和range()函数来生成数值元组。 注意&#xff1a;当元组中只包含一个元素时&#xff0c;需要在元素后面添加逗号&#xff0c;否则括号会被…

常见概念之事件驱动

简介 事件驱动是一种软件架构模式&#xff0c;其中系统的组件通过触发和响应事件来进行通信和协作。在事件驱动架构中&#xff0c;系统的各个组件之间通过发布和订阅事件的方式进行解耦&#xff0c;从而实现松散耦合和高度可扩展性。 一般工作流程 事件产生&#xff08;Even…

QCefView 在 Linux 下的编译(更新)

在前面的文章《QT 应用程序中集成浏览器》中已经介绍过 QCefView 的构建。这几天发现 QCefView 代码进行了更新,构建方式也发生了一点点变化,所以在此更新一下 QCefView 的编译方法。 QCefView 其实包含了两个项目,一个就是 QCefView 项目本身,另外一个就是 CefViewCore。…

Docker容器:Docker-Consul 的容器服务更新与发现

目录 前言 一、什么是服务注册与发现 二、 Docker-Consul 概述 1、Consul 概念 2、Consul 提供的一些关键特性 3、Consul 的优缺点 4、传统模式与自动发现注册模式的区别 4.1 传统模式 4.2 自动发现注册模式 5、Consul 核心组件 5.1 Consul-Template组件 5.2 Consu…

深度学习之基于Vgg16卷积神经网络乳腺癌诊断系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 基于VGG16卷积神经网络的乳腺癌诊断系统项目是一个结合深度学习技术和医学图像处理的创新项目&#xff0c;旨在提高…

代码随想录Day 40|Leetcode|Python|139.单词拆分 ● 关于多重背包,你该了解这些! ● 背包问题总结篇!

139.单词拆分 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回 true。 注意&#xff1a;不要求字典中出现的单词全部都使用&#xff0c;并且字典中的单词可以重复使用。 解题思路&#xff1a; 确定dp数组含义…

路飞吃桃递归问题

在写代码之前&#xff0c;补充两个知识点 1.C语言递归的模版 2.递归是怎么工作的 好!话不多说让我们开始吧&#xff1a; 我们知道路飞吃了n天&#xff0c;每次都是吃一半&#xff0b;1&#xff0c;知道最后一天&#xff0c;只有一个桃子了&#xff0c;所以就可以列出式子&…

列转行(spark 与presto语法)

一、Presto 语法 原始数据&#xff1a; 期望数据&#xff1a; 代码&#xff1a; SELECT info, value FROM ( select 张三 as name,18 as age,男 as gender,清华 as schoolunion allselect 李四 as name,18 as age,男 as gender,清华 as school ) as a CROSS JOIN UNNEST(…

Linux实现Flappy bird项目

目录 1、项目介绍 2、功能总结 3、前期准备 3.1 Ncurses库 3.2 信号机制 3.2.1 设置信号响应方式 3.2.2 设置定时器 4、代码实现 4.1 头文件引用及变量、函数定义 4.2 主函数 4.3 curses初始化 4.4 设置定时器 4.5 定时器响应函数 4.6 小鸟控制相关函数 4…

C语言 自定义类型——联合体

目录: 一、联合体是&#xff1f;声明计算内存大小 二、联合体的特点例如 三、联合体大小的计算规则&#xff1a; 四、应用习1习2 一、联合体是&#xff1f; 联合体和结构体差不多&#xff0c;但是其最大的区别在于联合体所有的成员共用一块内存空间。所以联合体也叫共用体。联…

stm32f103c8t6最小系统板

STM32F103C8T6最小系统板是为基于ARM Cortex-M3内核的STM32F103C8T6微控制器设计的电路板&#xff0c;它包含了单片机正常运行所需的最基本组件。以下是构成STM32F103C8T6最小系统板的基本部分&#xff1a; 单片机芯片&#xff1a;STM32F103C8T6本身&#xff0c;它是一款32位微…

Java_方法引用

方法引用就是把已经有的方法拿过来用&#xff0c;当作函数式接口中抽象方法的方法体。 条件&#xff1a; 1.引用处需要是函数式接口 2.被引用的方法需要已经存在 3.被引用的方法的形参和返回值需要跟抽象方法的形参和返回值保持一致 4.被引用方法的功能需要满足当前的要求 简…

搭建父模块和工具子模块

第一章 项目父模块搭建 1.1 nancal-idsa 作为所有工程的父工程&#xff0c;用于管理项目的所有依赖版本。 1.2 指定 pom 类型模块&#xff0c;删除 src 目录&#xff0c;点击Reload project 1.3 添加依赖 pom.xml <parent> <groupId>org.springframework.…

Python爬虫教程:入门爬取网页数据

1.遵守法律法规 爬虫在获取网页数据时&#xff0c;需要遵守以下几点&#xff0c;以确保不违反法律法规&#xff1a; 不得侵犯网站的知识产权&#xff1a;爬虫不得未经授权&#xff0c;获取和复制网站的内容&#xff0c;这包括文本、图片、音频、视频等。 不得违反网站的使用条…

【华为机考模拟题】Words、Vowel、计算字符串重新排列数

目录 一、Words 二、Vowel 三、计算字符串重新排列数 一、Words 每个句子由多个单词组成&#xff0c;句子中的每个单词的长度都可能不一样&#xff0c;假设每个单词的长度 Ni 为该单词的重量&#xff0c;你需要做的就是给出整个句子的平均重量 V。 输入&#xff1a; Who L…

如何设置ddns动态域名服务实现外网访问

在本地搭建好服务器&#xff0c;部署好web网站或其他应用后&#xff0c;需要在外网访问内网时&#xff0c;如何设置动态域名服务ddns&#xff0c;将主机的内网IP端口映射到外网访问&#xff0c;是我们需要面对的一个重要步骤。 内网发布外网&#xff0c;常见的有两种方案&…

【智能优化算法】金枪鱼群优化(Tuna Swarm Optimization,TSO)

金枪鱼群优化&#xff08;Tuna Swarm Optimization,TSO&#xff09;是期刊“Computational Intelligence and Neuroscience”&#xff08;IF&#xff1a;1.8&#xff09;的2021年智能优化算法 01.引言 金枪鱼群优化&#xff08;Tuna Swarm Optimization,TSO&#xff09;的主要…