對於不等式組:
x1 - x2 <= 0
x1 - x5 <= -1
x2 - x5 <= 1
x3 - x1 <= 5
x4 - x1 <= 4
x4 - x3 <= -1
x5 - x3 <= -3
x5 - x4 <= -3
求出滿足情況的x1~x5,這樣的問題我們叫做差分約束系統
差分約束系統的解法利用到了單源最短路徑問題中的三角形不等式。即對於任何一條邊u -> v,都有:
d(v) <= d(u) + w(u, v)
所以利用這個不等式,我們就可以用已知不等式來建圖了。
如x5-1>=x1,那麼就從x5連一條權值為-1的邊到x1上,以此類推,就可以成功建圖。
對於題目的問題,我們有不同的方式處理這張圖。
最基本的我們需要找乙個源點,但是這些被約束的點肯定不可以作為源點,所以我們建立乙個0號節點,對所有的點都連一條權值為0的邊,跑單源最短路時以這個點為出發點。
做題時可能會遇到不等式中的符號不相同的情況,但我們可以對它們進行適當的轉化
方程給出:x[n-1]-x[0]>=t ,可以進行移項轉化為: x[0]-x[n-1]<=-t。
方程給出:x[n-1]-x[0]=t,再利用(1)進行轉化即可
1.判定該不等式方程組是否有解
判斷是否有負環即可(證明的話可以自己畫一張有負權環的圖,很容易看出來),跑spfa
bool spfa()
exist[x] = 0;
q.pop_front();
sum -= dist[x];
for(int i = 0; i < g[x].size(); i++)}}
} return false;
}
2.求解不等式組
建完圖後跑最短路即可
/*
n個人分糖果,有m條限制
每個限制都要求a分到的糖果不能比b少超過c
要求算出1與n分到糖果的最大差異為多少
每條限制就是dis[a]+c>=dis[b],所以連一條從a到b的權值為c的邊
跑最短路即可,由於算1與n的最大差值,所以從從1號點開始跑
保證無負環
*/#include
#include
#include
using
namespace std;
typedef
long
long ll;
struct edge edge[
300005];
int head[
30005
],cnt =0;
void
add(
int u,
int v,
int val)
ll dist[
30005
],exist[
30005];
int s[
30005];
int top =0;
void
spfa
(int begin,
int n)
//起始點和點的數量
dist[begin]=0
;//起點距離為0
exist[begin]=1
;//exist表示在佇列裡
while
( top )
//如果從起點到t.num有大於等於n條邊,那麼說明一定有負環 }}
}}intmain()
for(
int i =
1; i <= m; i++
)spfa(1
,n);
printf
("%lld\n"
,dist[n]);
return0;
}
差分約束系統
差分約束 若 s a s b k 建一條b到a 的長度為k的邊 若s a s b k 建一條b到a 的長度為 k的邊 是求最小值的最長路 是求最大值的最短路 注意到最短路演算法的鬆弛操作 if d j d i w i j d j d i w i j 這其中的三角形不等式 d j d i w i j ...
差分約束系統
差分約束系統 對於差分不等式,a b c 建一條 b 到 a 的權值為 c 的邊,求的是最短路,得到的是最大值 對於不等式 a b c 建一條 b 到 a 的權值為 c 的邊,求的是最長路,得到的是最小值 存在負環的話是無解 求不出最短路 dist 沒有得到更新 的話是任意解 第三 一種建圖方法 設...
差分約束系統
差分約束系統 x1 x2 0 x1 x5 1 x2 x5 1 x3 x1 5 x4 x1 4 x4 x3 1 x5 x3 3 x5 x4 3 不等式組 1 全都是兩個未知數的差小於等於某個常數 大於等於也可以,因為左右乘以 1就可以化成小於等於 這樣的不等式組就稱作差分約束系統。這個不等式組要麼無解...