AcWing 1169 分糖果
分析:
本題考查差分約束。如果一個系統由n個變數和m個約束條件組成,其中每個約束條件形如xj-xi<=bk(i,j∈[1,n],k∈[1,m]),則稱其為差分約束系統(system of difference constraints)。亦即,差分約束系統是求解關於一組變數的特殊不等式組的方法。簡而言之,差分約束就是用來求解一種特殊的不等式組,這種不等式組裡面不等式的格式都是類似於Xa <= Xb + c這種形式,差分約束問題可以用求單源最短路的演算法來求解,一般使用spfa演算法求解。
1.差分約束問題與最短路問題的聯絡
在求解最短路的演算法中,核心的語句就是鬆弛操作,即d[v] > d[u] + w,就可以更新d[v]為d[u] + w了。在鬆弛某點v的距離的時候,會考察所有可以到達v的相鄰點,每次從v的相鄰點嘗試去鬆弛v之後,都會有d[v] <= d[u] + w,所以最終最短路徑上d[v] = min(d[i] + w[i])。如果將d[v]看作Xa,所有與之相鄰的點看作Xb,則求完最短路徑後的{Xa,Xb}的值一定滿足形如Xa <= Xb + c的不等式組的要求,也就是說,可以用spfa求最短路的過程來求解差分約束問題。
2.不等式組解的最小值與最大值
在求最短路的過程中,如果起點s的距離設為0,設從起點到某點t的路徑上依次經過x1,x2,x3三個點,對應的邊權依次是c1,c2,c3。則有x1 <= s + c1,x2 <= x1 + c2,x3 <= x2 + c3,可以推出x3 <= x2 + c3 <= x1 + c2 + c3 <= s + c1 + c2 + c3,s在這裡是定值,可以看出x3的值不會超過s + c1 + c2 + c3,也就是可以找到x3的最大值,但是不一定能夠知道x3的最小值,其他變數x1,x2也均有個上限,所以求最短路得到的解實際上是不等式組的最大解。當然,在鬆弛過程中d[v] = min(d[i] + w[i]),也就是為了滿足所有的約束條件,d[v]實際上是取所有鬆弛結果的最小值的。
再來考察求最長路的過程,將求最短路的鬆弛條件倒過來就可以求最長路了,即d[v] < d[u] + w時,就更新d[v]為d[u] + w,最後d[v] = max(d[i] + w[i]),也就是求完最長路後d[v] >= d[u] + w。同樣的如果起點s的距離設為0,設從起點到某點t的路徑上依次經過x1,x2,x3三個點,對應的邊權依次是c1,c2,c3。則有x1 >= s + c1,x2 >= x1 + c2,x3 >= x2 + c3,可以推出x3 >= x2 + c3 >= x1 + c2 + c3 >= s + c1 + c2 + c3,s在這裡是定值,可以看出x3的值不會小於s + c1 + c2 + c3,這樣就求出了x3的最小值了,也就是說最長路可以求出不等式組的最小解。注意,最長路演算法求解的是形如xa >= xb + c這種形式的不等式。
3.無約束的變數與無解情況
假設圖中有一點是孤立的,與其他點沒有關聯邊,則對應差分約束問題中的變數就是不受約束的,可以取任意值。再來考察無解的情況,如果求最短路時存在負環,假設負環上的點有x1,x2,x3,則有x2 <= x1 + c1,x3 <= x2 + c2,x1 <= x3 + c3,可以推出x1 <= x3 + c3 <= x2 + c2 + c3 <= x1 + c1 + c2 + c3,又c1 + c2 + c3 < 0(存在負環),所以x1 <= x1 + c1 + c2 + c3 < x1得出了x1 < x1的矛盾結論了,所以spfa演算法如果求出了負環則說明差分約束問題無解。
求最長路時如果存在正環,設正環上的點有x1,x2,x3,則有x2 >= x1 + c1,x3 >= x2 + c2,x1 >= x3 + c3,可以推出x1 >= x3 + c3 >= x2 + c2 + c3 >= x1 + c1 + c2 + c3,又c1 + c2 + c3 > 0(存在正環),所以x1 >= x1 + c1 + c2 + c3 > x1得出了x1 > x1的矛盾結論了。
4.差分約束問題的建圖
找到了spfa演算法可以求解差分約束問題,下面需要做的就是將不等式組轉化為圖。建圖的過程深刻的反映了求最短路最長路與差分約束問題的關聯。比如x1 <= x2 + 1,是建一條x2到x1長度為1的邊,還是建一條x1到x2長度為-1的邊呢?在最短路問題中,我們需要x1 <= x2 + c這種形式的不等式,遇見x1 >= x2 + 1形式的不等式就 轉化為了x2 <= x1 - 1,從而建立了x1到x2長度為-1的邊。而在最長路問題中,遇見x1 >= x2 + 1可以建一條x2到x1長度為1的邊,遇見x1 <= x2 + 1這種形式的不等式可以轉化為x2 >= x1 - 1,建立起了x1到x2長度為-1的邊。從而得出了一個重要結論:同一個不等式在最長路和最短路問題中建圖的方向是相反的,建立的邊權互為相反數,比如x1 <= x2 + 1,最短路問題是建一條x2到x1長度為1的邊,而在最長路問題中則是建一條x1到x2長度為-1的邊(x2 >= x1 - 1)。
其他型別的不等式:對於x1 < x2 + c形式的不等式,可以轉化為x1 <= x2 + c - 1形式;對於x1 = x2形式的不等式,可以轉化為x1 <= x2和x2 <= x1兩個不等式。
由於建的圖不一定連通,所以為了保證從起點出發一定能到達所有點,一般會建一個超級源點,從這個超級源點向各個點引一條長度為0的邊,即在不等式組中加上了x0 <= x1,x0 <= x2,...,x0 <=xn這麼多不等式。
下面迴歸本題,由於每個小朋友都需要分到糖,所以某個變數都不能小於1,所以建圖時可以由x0向各點引一條長度為1的邊,因為要求x1 >= 1等價於x1 >= x0 + 1,x0 = 0。本題是求差分約束的最小解,所以需要求最長路。spfa演算法求最長路時需要將距離陣列初始化為負無窮,當存在正環時存在某個點會一直被更新,所以更新超過一定次數後就說明無解。本題的spfa使用佇列會超時,所以要用棧替換佇列。