差分約束系統模板

2021-08-13 08:12:36 字數 1436 閱讀 8572

差分約束系統:如果乙個系統由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. 如果要求最大值想辦法把每個不等式變為標準 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 的形式,建圖後求最長路。這是兩個最基本的規則 算是吧 差分約束的精髓就在於建圖,而這玩意兒個人感覺沒什麼好辦法,只能靠不停做題去找到那種...