差分約束系統 模板

2021-07-02 13:36:47 字數 1972 閱讀 2522

差分約束系統:如果乙個系統由n個變數和m個約束條件組成,其中每個約束條件形如 xj - xi<= bk ( i , j ∈ [1,n],k ∈ [1,m]),則稱其為差分約束系統。 

例如如下的約束條件: 

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.新建乙個圖,n個變數看作n個頂點,m個約束條件作為m條邊。每個頂點vi分別對於乙個未知量,每個有向邊對應兩個未知量的不等式。 

2.為了保證圖的連通性,在圖中新加乙個節點vs,圖中每個節點vi都能從vs可達,建立邊w(vs,vi) = 0。 

3.對於每個差分約束xj - xi <= bk(這裡是小於等於號),則建立邊w(xi,xj) = bk。 

4.初始化dist = inf,dist[vs] = 0. 

5.求解以vs為源點的單源最短路徑,推薦用spfa,因為一般可能存在負值。 

如果圖中存在負權迴路,則該差分約束系統不存在可行解。 

vs到某點如果不存在最短路徑,即最短路為inf,則對於該點表示的變數可以取任意值,都能滿足差分約束的要求,如果存在最短路徑,則得到該變數的最大值。 

上述過程最終得到的解為滿足差分約束系統各項的最大值。 

注意點: 

1. 如果要求最大值想辦法把每個不等式變為標準 x - y <= k 的形式,然後建立一條從 y 到 x 權值為 k 的邊,變得時候注意 x - y < k => x - y <= k-1。 

2. 如果要求最小值的話,變為 x - y >= k 的標準形式,然後建立一條從 y到 x 權值為 k 的邊,求出最長路徑即可。 

3. 如果權值為正,用dijkstra,spfa,bellmanford都可以,如果為負不能用dijkstra,並且需要判斷是否有負環,有的話就不存在。

#include

#include

#include

#include

#include

#define inf 0x7fffffff

using

namespace

std;

const

int maxn = 1100;

const

int maxm = 30030;

struct edgenode

edges[maxm];

int head[maxn],dist[maxn],vis[maxn],outque[maxn],id;

void addedges(int u,int v,int w)

void spfa(int s,int n)

for(int i = head[u]; i != -1; i = edges[i].next)}}

}if(ans == -1) //出現負權迴路,不存在可行解

printf("-1\n");

else

if(dist[n] == inf) //可取任意值,都滿足差分約束系統

printf("-2\n");

else

printf("%d\n",dist[n]); //求使得源點 s 到 終點 t 的最大的值

}int main()

for(int i = 0; i < md; ++i)

//這裡不加也可以

// for(int i = 1; i < n; ++i)

// addedges(i+1,i,0);

spfa(1,n); //求使得源點 s 到 終點 t 的最大的值

}return

0;}

差分約束系統模板

差分約束系統 如果乙個系統由n個變數和m個約束條件組成,其中每個約束條件形如 xj xi bk i j 1,n k 1,m 則稱其為差分約束系統。例如如下的約束條件 x1 x2 0 x1 x5 1 x2 x5 1 x3 x1 5 x4 x1 4 x4 x3 1 x5 x3 3 x5 x4 3 上述過...

差分約束系統 模板

先來理解一下 有乙個已經求好的dis最短路陣列,有一條邊x y權值為w,那麼一定存在dis y dis x w,即dis y dis x w 那麼什麼是差分約束系統呢,就是給我一些不等式,我可以用最短路的思想把他們轉化成圖 即差分約束系統 然後加乙個超級原點0,0到其他所有點的地方初始化為0以後,去...

差分約束 模板

如果需要求的是兩個變數差的最大值,那麼需要將所有不等式轉變成 leq 的形式,建圖後求最短路 如果需要求的是兩個變數差的最小值,那麼需要將所有不等式轉化成 geq 的形式,建圖後求最長路。這是兩個最基本的規則 算是吧 差分約束的精髓就在於建圖,而這玩意兒個人感覺沒什麼好辦法,只能靠不停做題去找到那種...