【学习笔记】差分约束
1.【学习笔记】Kruskal 重构树2.【学习笔记】网络流3.【学习笔记】高级数据结构4.【学习笔记】线性基5.【学习笔记】Link Cut Tree6.【学习笔记】字符串后缀算法7.【学习笔记】字符串回文算法8.【学习笔记】组合数学9.【学习笔记】多项式 1:基础操作10.【学习笔记】多项式 2:集合幂级数11.【学习笔记】多项式 3:多项式运算12.【学习笔记】Prufer 序列13.【学习笔记】多项式 4:生成函数14.【学习笔记】DP 套 DP15.【学习笔记】图的连通性
16.【学习笔记】差分约束
17.【学习笔记】长链剖分18.【学习笔记】2-SAT19.【学习笔记】根号算法20.【学习笔记】Primal-Dual 原始对偶算法21.【学习笔记】Bostan-Mori 算法22.【学习笔记】狄利克雷卷积与高级筛法23.【学习笔记】DP 优化 1:基础优化24.【学习笔记】DP 优化 2:动态 DP25.【学习笔记】李超线段树26.【学习笔记】优化建图27.【学习笔记】Segment Tree Beats28.【学习笔记】插头 DP29.【学习笔记】任意模数多项式乘法30.【学习笔记】SG 函数与 SG 定理31.【学习笔记】类欧几里得算法32.【学习笔记】狄利克雷前/后缀和/差分33.【学习笔记】DSU on Tree34.【学习笔记】DP 优化 3:闵可夫斯基和优化 DP35.【学习笔记】笛卡尔树36.【学习笔记】Miller-Rabin 算法37.【学习笔记】DP 优化 4:决策单调性38.【学习笔记】DP 优化 5:wqs 二分优化 DP39.【学习笔记】边分治40.【学习笔记】KMP 相关算法41.【学习笔记】概率生成函数42.【学习笔记】离散对数和剩余概述#
差分约束系统,是由 个元素和 个约束条件构成的,其中每个约束条件形如 。
求解#
移项得到 ,这样三角形不等式的形式类似最短路中的松弛,即由 向 连 权值的边,最短路即满足约束条件。
这样便需要一个源点,原图不一定连通,因此建出超级源点 ,且规定 ,即 ,由 向 连 权值的边。
这样的负权图最短路可以使用 已死算法 SPFA 来求出。
点击查看代码
int n,m;
struct Graph{
struct edge{
int v,w;
edge()=default;
edge(int v_,int w_):v(v_),w(w_){}
};
vector<edge> E[maxn];
inline void add_edge(int u,int v,int w){
E[u].push_back(edge(v,w));
}
int dis[maxn],cnt[maxn];
bool vis[maxn];
inline void SPFA(){
queue<int> q;
memset(dis,0x3f,sizeof(dis));
dis[n+1]=0,cnt[n+1]=0,vis[n+1]=1;
q.push(n+1);
while(!q.empty()){
int u=q.front();
vis[u]=0;
q.pop();
for(edge e:E[u]){
int v=e.v,w=e.w;
if(dis[u]+w<dis[v]){
dis[v]=dis[u]+w,cnt[v]=cnt[u]+1;
if(cnt[v]>=n) return printf("NO\n"),void();
if(!vis[v]){
vis[v]=1;
q.push(v);
}
}
}
}
for(int i=1;i<=n;++i) printf("%d ",dis[i]);
printf("\n");
}
}G;
int main(){
n=read(),m=read();
for(int i=1;i<=n;++i) G.add_edge(n+1,i,0);
for(int i=1;i<=m;++i){
int u=read(),v=read(),w=read();
G.add_edge(v,u,w);
}
G.SPFA();
return 0;
}
对约束条件的调整#
一些简单的变形:
对解的特殊限制#
事实上,当 为一组解时, 同样为一组解。因此不等式组要么无解要么有无数组解,无解情况即为没有最短路也就是存在负环。
而在初始的设计中,,当需要求出特定范围的解时,可以通过限定 的初始值或 的值来规定。假设将值修改为 ,则本质上是有 的限定。
值得注意的是,最短路求出的结果一定是所有解中最大的。证明考虑最短路树,树边一定满足 而一旦增加 的值就会使答案不合法。
如果要求出满足 的所有解中和最小的值,该如何处理?
首先可以通过变号得到 ,这一点可以对 进行修改。这样所有的 值都已经取反,则 变作 ,即 有向边方向改变,边权不变,此时最短路得到的最大解与要求最小解互为相反数。这本质上和求最长路时没有区别的。
例题#
Luogu-P3275 SCOI 2011 糖果#
建模比较容易,关键是 SPFA 被卡了。
发现边权只有 或 ,那么一个 SCC 中存在边权 即无解,这样每个 SCC 都一定相等,最短路用拓扑排序求出。
参考资料#
-
OI Wiki
作者:SoyTony
出处:https://www.cnblogs.com/SoyTony/p/Learning_Notes_about_Difference_Constraints.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效