如果一个不等式组由 n 个变量和 m 个约束条件组成,形成 m 个形如x[ j ]-x[ i ]≤k(i,j∈[1,n] 且 k 为常数)的不等式,则称其为差分约束系统。换句话说,差分约束系统就是求解一组变量的不等式组的算法。
连边后求最短路
将x[ j ]−x[ i ]≤k 变形为 x[ j ]≤k+x[ i ],即从 i 到j 连一条边权为 k 的边。加入超级源点后求最短路,得到xi≤0 所有 x 最大解。
连边后求最长路
将x[ j ]−x[ i ]≤k 变形为 x[ i ] ≤ x[ j ]-k,即从 j 到 i 连一条边权为 −k 的边。加入超级源点后求最长路,得到 xi≥0 所有 x 最小解

1 #include<iostream>
2 #include<queue>
3 #include<cstdio>
4 #include<cstring>
5 using namespace std;
6 #define N 5005
7 #define M 11000
8 int n,m,cnt;
9 int head[N];
10 struct edge{
11 int to,w,nxt;
12 }e[M];
13 void add(int u,int v,int w){
14 e[++cnt].w=w;
15 e[cnt].to=v;
16 e[cnt].nxt=head[u];
17 head[u]=cnt;
18 }
19 int dis[5005],tot[5005];//tot为入队次数
20 bool vis[N];
21 queue<int>q;
22 bool spfa(){
23 for(int i=1;i<=n;i++) dis[i]=0x7ffffff;
24 memset(vis,0,sizeof(vis));
25 q.push(0);dis[0]=0;vis[0]=1;
26 while(q.size()){
27 int u=q.front();q.pop();
28 vis[u]=0;
29 for(int i=head[u];i;i=e[i].nxt){
30 int v=e[i].to;
31 if(dis[v]>dis[u]+e[i].w){
32 dis[v]=dis[u]+e[i].w;
33 if(!vis[v]){
34 vis[v]=1;q.push(v);
35 }
36 tot[v]++;
37 if(tot[v]==n)return 0;
38 }
39 }
40 }
41 return 1;
42 }
43 int main(){
44 scanf("%d%d",&n,&m);
45 for(int i=1;i<=n;i++)add(0,i,0);
46 for(int i=1;i<=m;i++){
47 int a,b,c;
48 scanf("%d%d%d",&a,&b,&c);
49 add(b,a,c);
50 }
51 if(!spfa())
52 printf("NO");
53 else
54 for(int i=1;i<=n;i++)
55 printf("%d ",dis[i]);
56 return 0;
57 }
例题:
https://www.luogu.com.cn/problem/P1250
poj1201
(也可用贪心和线段树优化)
跑最长路
1 #include<bits/stdc++.h>
2 using namespace std;
3 const int N = 1000005;
4 const int M = 1000005;
5 int n,m;
6 int dis[N];
7 bool vis[N];
8 int head[N],num;
9 struct Edge{
10 int to,next,w;
11 }e[M];
12 void add(int u,int v,int w){
13 e[++num].w=w;
14 e[num].to=v;
15 e[num].next=head[u];
16 head[u]=num;
17 }
18 void spfa(int x){
19 queue<int> q;
20 q.push(x);
21 for(int i=0;i<=n+1;i++)dis[i]=1;
22 dis[x]=0;vis[x]=1;
23 while(!q.empty()){
24 int u=q.front();q.pop();
25 vis[u]=0;
26 for(int i=head[u];i;i=e[i].next){
27 int v=e[i].to;
28 if(dis[v]>dis[u]+e[i].w){
29 dis[v]=dis[u]+e[i].w;
30 if(!vis[v]){
31 q.push(v);
32 vis[v]=1;
33 }
34 }
35 }
36 }
37 }
38 int main(){
39 int a,b,c,minn=0x3f3f3f3f;
40 memset(head,-1,sizeof(head));
41 cin>>n>>m;
42 int y=n+1;
43 for(int i=0;i<=n;i++) add(y,i,0);
44 for(int i=1;i<=m;i++){
45 cin>>a>>b>>c;
46 add(b,a-1,-c);
47 }
48 for(int i=1;i<=n;i++){
49 add(i-1,i,1);
50 add(i,i-1,0);
51 }
52 spfa(y);
53 for(int i=0;i<=n;i++)
54 minn=min(minn,dis[i]);
55 cout<<dis[n]-minn<<endl;
56 return 0;
57 }
来源:https://www.cnblogs.com/liukx/p/12404245.html
