首页 > 其他分享 >差分约束 笔记

差分约束 笔记

时间:2024-08-12 20:19:42浏览次数:10  
标签:cnt matrix int 笔记 约束 vis ge 差分 dis

差分约束 笔记

给定约束 \(n\) 个未知数的 \(m\) 个约束条件,求满足条件的未知数的其中一个整数解。

\(m\) 个约束条件如下:

\[\left \{ \begin{matrix} x_{c_1} + w_1 \ge x_{c'_1}\\ x_{c_2} + w_2 \ge x_{c'_2}\\ x_{c_3} + w_3 \ge x_{c'_3}\\ \dots \\ x_{c_m} + w_m \ge x_{c'_m} \end{matrix} \right. \]

通俗的讲,将 \(u = c_i, v = c'_i\),\(x_u + w \ge x_v\),而 \(x_u\) 表示第 \(u\) 个未知数,放在 \(a\) 数组里表示 \(a_u\)。

于是,式子变形成:

\[a_u + w \ge a_v \]

换个变量名,\(a \to dis\):

\[dis_u + w \ge dis_v \]

想到了三角不等式,最短路的松弛操作,于是我们可以将这个式子理解成 \(u \to v\) 有一条权值为 \(w\) 的有向边。

于是可以建图。

例如下面不等式:

\[\left \{ \begin{matrix} dis_2 + 3 \ge dis_1 \\ dis_3 + (-2) \ge dis_2 \\ dis_3 + 1 \ge dis_1 \\ \end{matrix} \right. \]

可以建图为:并跑最短路,\(dis\) 数组即为答案。

当然,原式也可以转换成:

\[x_i - w \le x_i' \]

也就是说,我们可以反向建边并跑最长路。观察出最长路的 \(dis\) 数组会比最短路的 \(dis\) 数组要小,所以用最短路跑出来的是大解,用最长路跑出来的是小解。

无解情况即有负环。

所以跑一边 SPFA 即可。

注意,在建图中,可以用一个编号为 \(0\) 的超级源点连接所有点,边权为 \(0\)。

#include <bits/stdc++.h>
#define pb push_back
using namespace std;
using ll = long long;
const int N = 5e3 + 5;

struct edge{
	int v, w;
};

int n, m, dis[N], vis[N], cnt[N];
vector<edge> g[N];

bool spfa() {
	memset(dis, 0x3f, sizeof dis);
	dis[0] = 0, vis[0] = 1;
	queue<int> q;
	q.push(0);
	while (!q.empty()) {
		int u = q.front();
		q.pop();
		vis[u] = 0;
		for (auto x : g[u]) {
			int v = x.v, w = x.w;
			if (dis[u] + w < dis[v]) {
				dis[v] = dis[u] + w;
				cnt[v] = cnt[u] + 1;
				if (cnt[v] > n)	return false;
				if (vis[v])	continue;
				vis[v] = 1;
				q.push(v);
			}
		}
	}
	return true;
}

signed main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	
	cin >> n >> m;
	for (int i = 1; i <= m; i++) {
		int u, v, w;
		cin >> u >> v >> w;
		g[v].pb({u, w});
	}
	for (int i = 1; i <= n; i++)   g[0].pb({i, 0});
	if (!spfa())	cout<<"NO";
	else {
		for (int i = 1; i <= n; i++)	cout << dis[i] << " ";
	}
	return 0;
}

标签:cnt,matrix,int,笔记,约束,vis,ge,差分,dis
From: https://www.cnblogs.com/Mason123456/p/18355662

相关文章

  • UE5学习笔记9-创建一个小窗口提示人物是否和武器重叠
    一、目标    创建一个UsrWidget去显示如果人物和武器重叠显示窗口,如果人物和武器不重叠将窗口隐藏二、创建窗口并显示    1.创建一个窗口蓝图类,命名为PickUpWidget,这个蓝图类不需要C++类,在对应文件夹中单机右键选择用户界面的控件蓝图    2.在界......
  • Java学习笔记4--Java跨平台原理
    一、Java程序运行机制计算机高级语言按照程序的执行方式可以分为编译型语言和解释型语言。编译型语言:编写的程序源代码需要通过编译器生成机器语言目标文件,在计算机上直接执行目标文件。编译型语言的代表是C、C++等。解释型语言:源代码被解释器逐行解释并执行,因此无需编译器生......
  • 积性函数和狄利克雷卷积学习笔记
    积性函数和狄利克雷卷积学习笔记积性函数定义若函数\(f(x)\)满足\(f(ab)=f(a)f(b)\),其中\(a,b\)互质,我们称这个函数是积性函数。若\(a,b\)不互质则是完全积性函数。常见积性函数狄利克雷卷积定义也叫狄利克雷乘积。形如下式:\[h(n)=\sum_{ab=n,a>0,b>0}f(a)g(b)\]......
  • Java学习笔记3--java编译和运行的CMD命令
    windows下利用cmd命令行可以调用jdk里的javac.exe和java.exe对java文件进行编译和执行,前提是jdk已成功安装并正确配置相关环境变量执行命令解析:javac命令用于将java源文件编译为class字节码文件,如:javacHelloWorld.java。运行javac命令后,如果成功编译没有错误的话,会出现......
  • 《ImageNet: A Large-Scale Hierarchical Image Database》李飞飞论文阅读笔记
    OpenSNN开思通智网,官网地址:https://w3.opensnn.com/2024年8月份"O站创作者招募计划"快来O站写文章,千元大奖等你来拿!“一起来O站,玩转AGI!”论文地址:《ImageNet:ALarge-ScaleHierarchicalImageDatabase》这篇论文是关于一个叫做“ImageNet”的大型图像数据库的介绍。......
  • opencv学习笔记(一)
    前言本文为本人观看b站视频学习opencv的笔记分享,如有错误欢迎指正,如有侵权联系我删除,视频链接一、ReadImagesVideosandWebcams#include<opencv2/imgcodecs.hpp>#include<opencv2/highgui.hpp>#include<opencv2/imgproc.hpp>#include<iostream>usingnamespaces......
  • 《数据资产管理核心技术与应用》读书笔记-第三章:数据血缘
    《数据资产管理核心技术与应用》是清华大学出版社出版的一本图书,全书共分10章,第1章主要让读者认识数据资产,了解数据资产相关的基础概念,以及数据资产的发展情况。第2~8章主要介绍大数据时代数据资产管理所涉及的核心技术,内容包括元数据的采集与存储、数据血缘、数据质量、数据监控与......
  • Java基础-学习笔记08
    01类变量、类方法、main方法、代码块类变量(静态变量)类变量也叫静态变量/静态属性,是该类的所有对象共享的变量,任何一个该类对象去访问它时,取到的都是相同的值,同样任何一个该类的对象去修改它时,修改的也是同一个变量。关于静态变量在内存中的存放地址,有两种说法,①认为静态变量......
  • leetcode刷题笔记8.5-8.9
    刷题笔记8.5-8.9刷题顺序依照labuladong算法小抄两数之和(8.5)初始化数组:int[]num=newint<length>;int[]num={1,2,3,4};其中数组名代表指针变量,故不可以直接将数组名a赋值给数组名b错误的复制:int[]b=a;数组元素复制:假设数组nums的元素复制到numsSort中:int[]......
  • 结构开发笔记(二):solidworks软件(一):介绍、下载和安装过程
    前言  部分零件外壳需要结构设计,在proE和solidworks中经过过程对比发现solidworks相对比较符合使用习惯,所以在有proE基础的前提下还是更换了solidworks来进行产品的结构零件设计,其图形直接可以进行3D打印,实现定制化的零件。  本篇介绍solidworks,下载并安装。 Solidwo......