演算法簡介
差分約束系統是一種特殊的n元一次不等式組,它包含n個變數x1−
xn
x_1 - x_n
x1−xn
以及m個約束條件,每個約束條件都是由兩個變數作差構成的,形如xi−
xj
<=c
kx_i - x_j <= c_k
xi−xj
<=c
k,其中c
kc_k
ck是常數(可以為負),1<= i , j <= n, 1 <= k <= m。我們要解決的問題是:求一組解,x1=
a1,x
2=a2
,...
,xn=
an
x_1 = a_1, x_2 = a_2 ,... , x_n = a_n
x1=a1
,x2
=a2
,..
.,xn
=an
使得所有約束條件都得到滿足。
差分約束系統的每個約束條件xi−
xj
<=c
kx_i - x_j <= c_k
xi−xj
<=c
k可以變形為x
i<=x
j+ck
x_i <= x_j + c_k
xi<=x
j+c
k,這與單源最短路中的三角不等式 dis[ y ] <= dis[ x ] + z非常類似,因此可以把每個變數x_i 看作有向圖中的乙個節點 i ,對於每個約束條件xi−
xj
<=c
kx_i - x_j <= c_k
xi−xj
<=c
k, 從節點j 向節點 i 連一條長度為 c
kc_k
ck 的有向邊。
注意到如果集合a是一組解,那麼a+d也是一組解(作差後d被消掉)。
設dis[0] = 0,以0為起點求單源最短路,若圖中存在負環則差分約束系統無解。否則,xi=
dis[
i]
x_i = dis[i]
xi=di
s[i]
就是差分約束系統的一組解。
在某些題目中,xi−
xj
>=c
kx_i - x_j >= c_k
xi−xj
>=c
k,仍可以看作是從 j 到 i 連成長度為 c
kc_k
ck的有向邊,只是改為計算單源最長路徑,若圖中存在正環則無解。當然也可以不等式兩邊同時取負,使得變換成標準形式。
結論差分約束是基於三角不等式的乙個推廣。關鍵在於根據題意構造出恰當的狀態,建立狀態間的不等關係,並證明滿足不等式的乙個解與原問題一一對應,然後便可以利用spfa演算法求解。其優點是不等式關係明顯,易於理解,缺點是適用性窄。
例題模板
zju1420 出納員問題
題意簡述:
有一家24小時營業的超市,需要僱傭一批出納員。一天中每個小時需要出納員的最少數量為r0,r1,r2,…,r23。有n個人申請這項工作,每個申請者,從乙個特定時刻ti,開始連續工作恰好8個小時。(ti為整數,且0<=ti<=23 )。你的任務是計算出需要僱傭出納員的最少數目,滿足在每一時刻k,至少有ri名出納員在工作。
解題思路:
真的有點難想啊,首先我們要假設num[i] 為 i 時刻能夠開始工作的人數,x[i] 為實際僱傭人數,那麼x[i] <= num[i] 。而r[i]是i 時刻至少需要的人數,這由題目給出。
我們令s[i] = x[i] + x[i-1] + … + x[1] ,顯然我們就會得到關於 s 和 num 的一組不等式,如果想要答案正確,需要找到所有隱含的條件:
s[i] - s[i-1] >= 0 //(0 <= i <= 23)
s[i-1] - s[i] >= -num[i] // (0<=i<=23)
s[i] - s[i-8] >= r[i] //(8<=i<=23)
s[i] - s[i+16] >= r[i] - s[23] // (0 <= i <= 7)
注意到,s[23]本是未知數,但是我們將它作為常數處理,具體做法是我們遍歷s[23]的所有可能的值,並依次進行一次spfa,嘗試找尋僱傭最小人數 且使得不等式組成立的可能。 注意如果 i 從0開始,那麼鄰接表存有向圖,head節點就不能初始化為0,防止死迴圈超時。
**示例:
#include#include#include#includeusing namespace std;
int t,n,r[30],num[30];
const int n = 1e5+10;
const int inf = 0x3f3f3f3f;
int head[n],ver[n],edge[n],nex[n],tot;
int dis[100],vis[100],ts[100];
void addedge(int x,int y,int z)
queueq;
bool spfa(int s)
//printf("%d %d %d\n",x,y,dis[x]);}}
return dis[24] == s;
}bool solve(int z)
int main()
if(flag) puts("no solution");
}return 0;
}
參考資料 差分約束系統
差分約束 若 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就可以化成小於等於 這樣的不等式組就稱作差分約束系統。這個不等式組要麼無解...