差分约束
没什么好写的。
算法思路
有
个未知数 ,给定 个形如 ( 为常数)的不等式。
求一组最大解和最小解。使得所有的不等式成立。
我们以最小解为例讲解。
观察不等式,发现
差分约束中存在无解的情况,也就是说在任意一刻我们都无法求得正解,也就是说差分约束系统形成的图中存在负环,直接用 SPFA 判断即可
因为
例题
例 :【模板】差分约束
没说最大解或最小解,直接求一个就好
点击查看代码
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
const int N=5e3+10;
int idx,ver[N],to[2*N],nxt[2*N],val[2*N],n,m,mk[N],dis[N],d[N];
queue<int>q;
void add(int x,int y,int z){
to[++idx]=y,nxt[idx]=ver[x],ver[x]=idx,val[idx]=z;
}
int main(){
scanf("%d %d",&n,&m);
for(int i=1,u,v,w;i<=m;i++){
scanf("%d %d %d",&u,&v,&w);
add(v,u,w);mk[u]=1;
}
for(int i=1;i<=n;i++)if(!mk[i])add(0,i,0);
memset(dis,0x3f,sizeof(dis));
memset(mk,0,sizeof(mk));
q.push(0),mk[0]=1,dis[0]=0,d[0]=1;
while(q.size()){
int t=q.front();q.pop();
mk[t]=0;
for(int i=ver[t];i;i=nxt[i]){
int tp=to[i];
if(dis[t]+val[i]<dis[tp]){
dis[tp]=dis[t]+val[i];
if(!mk[tp]){
if(++d[tp]>=n){
cout<<"NO"<<endl;
return 0;
}
q.push(tp),mk[tp]=1;
}
}
}
}
for(int i=1;i<=n;i++){
cout<<dis[i]<<" ";
}
return 0;
}
例 :小 K 的农场
主要将转换边权,设第
- 情况一:
可转换为 - 情况二:
可转换为 - 情况二:
可转换为
直接跑最短路即可
例 :[SCOI2011] 糖果
数据非常大,直接跑 SPFA 行不通。
转换为边权后,发现边权只有
缩点后跑拓扑排序就好
例 :[1007] 倍杀测量者
显然,
我们发现,对于类似
另外,对于差分约束中的有常量的情况,例如:已知
真的无法忍受有精度问题和带有高中数学知识的题目!
毕竟我连小学数学都玩不明白。
The End
感觉没什么用,大概会一点就好了,以后慢慢练。
我怎么连不等式都转换不好
upd:差分约束简单?什么人机话,我当时到底有多糖啊!
马上补一下差分约束
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话