差分約束,是乙個建模的思想。也就是把一些代數上的約束關係建模成圖論的相關問題。差分約束的一些題目往往對思維上建模能力的要求比較高,而對具體演算法的考察卻比較低,所以做差分約束的題目,一般建模之後會給人一種敲板子的那種流暢和虐題的感覺哈哈哈哈。
我們從最簡單的不等式說起。(不等式的關係就是代數式之間的大小約束關係)
已知 x1−
x0≤2
x2−x0≤7
x3−x0≤8
x2−x1≤3
x3−x2≤2
如果要求x3
−x0 的最大值,應該怎麼做呢?
前面已經提到,用差分約束的思想可以把乙個代數的不等關係抽象成圖上的一些問題。我們觀察第乙個不等式,可以寫成:x1
≤x0+
2 如果把x0
等看成某點到某源點的距離,那麼這個不等式就代表0號點到1號點有一條長度為2的有向邊。最後我們可以得到這樣一張圖:
然後這道題目就變成了0到3的最短距離了。用圖論最短路演算法的某一種就能求出來。
這樣我們就完成了乙個從約束的關係到圖論模型的乙個轉換了。
預備知識
圖論最短路演算法
在上面的引子中我們已經可以總結道:對於每個不等式x[
i]−x
[j]≤
a[k]
,我們可以從j到i建立一條有向邊,權值為a[
k] x
[j]−
x[i]
的最大值就是求i到j的最短路。
此部分**大佬部落格
如果還沒有完全理解,我們可以先來看乙個簡單的情況,如下三個不等式:如果還沒有完全理解,我們可以先來看乙個簡單的情況,如下三個不等式: b−
a≤c
c−b≤
a c−
a≤b
我們想要知道c - a的最大值,通過(1) + (2),可以得到 c−
a≤a+
c ,所以這個問題其實就是求mi
n 。將上面的三個不等式按照數形結合的方式建圖,可以得到:
我們發現mi
n 正好對應了a到c的最短路,而這三個不等式就是著名的三角不等式。將三個不等式推廣到m個,變數推廣到n個,就變成了n個點m條邊的最短路問題了。
上文提到最短路的時候,會出現負環或者根本就不可達的情況,所以在不等式組轉化的圖上也有可能出現上述情況,先來看負權圈的情況,如圖下圖為5個變數5個不等式轉化後的圖,需要求得是x[
t]−x
[s] 的最大值,可以轉化成求s到t的最短路,但是路徑中出現負權圈,則表示最短路無限小,即不存在最短路,那麼在不等式上的表現即x[
t]−x
[s]≤
t 中的t無限小,得出的結論就是 x[
t]−x
[s] 的最大值 不存在。
(看到負環時是不是有用bellman或者spfa的衝動?)
再來看另一種情況,即從起點s無法到達t的情況,如圖,表明x[
t]和x[s
] 之間並沒有約束關係,這種情況下x[
t]−x
[s] 的最大值是無限大,這就表明了x[
t]和x[s
] 的取值有無限多種。
在實際問題中這兩種情況會讓你給出不同的輸出。綜上所述,差分約束系統的解有三種情況:
1. 有解
2. 無解
3. 無限多解;
然後,我們將問題進行乙個簡單的轉化,將原先的」
≤ 」變成」>=」,轉化後的不等式如下:
b - a >= c (1)
c - b >= a (2)
c - a >= b (3)
然後求c−a
的最小值,模擬之前的方法,需要求的其實是ma
x ,於是對應的是圖上從a到c的最長路。同樣可以推廣到n個變數m個不等式的情況。
我們發現,很多約束關係並不是標準的
≤ ,有時候會出現一些等號啊等等。
對於等式a−
b=c 等號的處理就是把它拆成兩個不等式: a−
b≤c
a−b≥
c 對於<>
,在整數中我們可以轉化成
≤≥ 例如我們把
a<
b 寫成了
a<=b−
1 (滿足a、
b∈z )
狡猾的商人
題面傳送門
這道題目的大意就是:給一些賬本上的資訊,讓你判斷賬本是真是假。如果有第s月到第t月總共收益為w,那麼我們可以發現,從第s-1個月末開始,商人拿了w元錢。如果令dis[i]為第i個月末的收入,那麼我們有:di
s[s−
1]+w
=dis
[t] 。這是乙個再將這個等式標準化,可以得到:di
s[s−
1]+w
≤dis
[t] 和di
s[s−
1]+w
≥dis
[t] ,所以我們可以從s-1到t建一條w長度的邊,同時從t到s-1建一條-w長度的邊。建圖好之後,我們的差分約束就完成了,判斷這個圖是否符合現實賬本的實際的方法就是用跑spfa判斷是否存在負環。如果存在負環就與現實矛盾了。(想一想,為什麼?)
我們這裡的spfa採用dfs版本,只要某乙個點在同一條路徑上出現多次,我們可以認為它是在負環上了。
#include
#define maxn 105
#define inf 2e9
using
namespace
std;
inline
int read()
int w,n,m;
namespace graph
; vector
g[maxn];
void init()
);g[t].push_back((node));}}
}using
namespace graph;
//建圖
namespace shortest
dis[v.to]=dis[u]+v.val;
//更新最短路
spfa(v.to);
//繼續dfs}}
vis[u]=0;return;
}}using
namespace shortest;
//最短路
int main()
if(flag)printf("false\n");
else
printf("true\n");
for(int i=0;i<=n;i++)
flag=false;
}return
0; }
差分約束詳解
一直不知道差分約束是什麼型別題目,最近在寫最短路問題就順帶看了下,原來就是給出一些形如x y b不等式的約束,問你是否滿足有解的問題 好神奇的是這類問題竟然可以轉換成圖論裡的最短路徑問題,下面開始詳細介紹下 比如給出三個不等式,b a k1,c b k2,c a k3,求出c a的最大值,我們可以把...
差分約束系統詳解
差分約束系統 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就可以化成小於等於 這樣的不等式組就稱作差分約束系統。這個不等式組要麼無解...
差分約束系統詳解
差分約束系統詳解 一直不知道差分約束是什麼型別題目,最近在寫最短路問題就順帶看了下,原來就是給出一些形如x y b不等式的約束,問你是否滿足有解的問題 好神奇的是這類問題竟然可以轉換成圖論裡的最短路徑問題,下面開始詳細介紹下 比如給出三個不等式,b a k1,c b k2,c a k3,求出c a的...