背景是給你若干個不等式,形如xi−xj≤bxi−xj≤b,需要你判斷x的解的存在性或是最優解。
而差分約束系統即為這個問題轉化為乙個圖論問題,進而跑最短路來判環或求最值距離(最優解)。
這裡轉化的原理是三角不等式,即d(v)−d(u)≤cost(u,v)d(v)−d(u)≤cost(u,v),可以建為一條花費為cost(u,v)cost(u,v)的邊(u,v)(u,v)。
常規操作:
根據題意找出一些不等式來建圖,(特別注意:題目中的隱藏條件,這個非常關鍵),以及可能還需要由已知結論推出二級結論的不等式來更優秀的建邊。
判環:一些問題建圖後不存在最優解,而存在無限減小/增大的負環/正環,需要利用spfaspfa來判進佇列次數來判斷,注意,在判負環時,不能用dijkstradijkstra。
最值距離(最優解):對於求ximaxximax,便是求最短路;對於求ximinximin,便是求最長路,或者可以將邊權變負,也可以求最短路。
建圖:當求ximinximin時,即求最長路,那麼將不等式轉化為d(v)≥d(u)+kd(v)≥d(u)+k,即建一條花費為kk的邊(u,v)(u,v);同理,求ximaxximax時,即求最短路,將不等式轉化為d(v)≤d(u)+kd(v)≤d(u)+k,即建一條花費為kk的邊(u,v)(u,v)。注意,有時題目只給出d(v)d(u)+kd(v)>d(u)+k,這時就需要放縮一下,取到等號,即d(v)−d(u)≤k−1d(v)−d(u)≤k−1或d(v)−d(u)≥k+1d(v)−d(u)≥k+1。
另外,建圖時還要專門設乙個源點ss,s連向圖中所有的點,且邊權為00,這樣保證了圖的連通性。
code(模板):
判環:queueq;
int dis[n];
char vis[n];
int cnt[n];
void spfa()} }
}return 1;最優解:
一般就是在判環(判解的存在性)的同時,已經求出最優解,若有解,即輸出,否則,一般是impossible(據題意)。這裡就不再贅述。
summary:
個人感覺差分約束系統是比較冷門的知識點,而且應用範圍比較窄,
必須是不等式吧,這是判斷是否用該演算法的關鍵。
另外,它其實也是最短路的一種,在圖論問題中,一些問題有可能會切到更多的分。
補充:判斷負環要用dfs+spfa
**
bool
spfa
(int u)
} vis[u]=0
;return1;
}
負環與差分約束
跑 spfa 時,設 sp cnt x 表示從 x 入隊次數,若更新時,sp cnt y gt n 則說明圖中有負環,演算法正常結束,則圖中無負環 bool spfa return false 差分約束系統即為 n 元一次不等式組,每個約束條件都是由兩個變數作差構成的,形如 x i x i leqs...
POJ 1364 King 差分約束 找負環
嘛,雖然是一道水題 模板題,不過還是學到了很多東西的,記錄一下。首先題目給出的不等式是小於,但是差分約束系統只能處理小於等於的情況,所以要轉化成小於等於的進行處理。對於整數處理方法非常簡單 然後是找負環的情況,其實不需要考慮圖連不連通,只要一開始就把所有的點的d置成0,然後都push進佇列裡面就好了...
POJ3169 簡單差分約束 記得判負環
題意 有n頭牛,他們按順序排成了一排,有些牛關係比較好,他們的距離不能超過某個距離,還有些牛關係不好,他們之間的距離不能小於某個距離,可能會有多頭牛擠在同一位置上,問1號牛和n號牛之間的最大距離是多少,如果不存在滿足條件的排列則輸出 1,如果距離無限大則輸出 2.分析 令d i 表示第i頭牛的位置,...