差分約束系統

2021-09-25 12:45:09 字數 1963 閱讀 9695

對於不等式組:

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就可以化成小於等於 這樣的不等式組就稱作差分約束系統。這個不等式組要麼無解...