差分約束系統及判斷負環

2021-09-27 15:43:14 字數 1296 閱讀 5968

簡介:

背景是給你若干個不等式,形如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頭牛的位置,...