關於差分約束,《演算法導論》講的挺明白的了。有一點要注意的是x1-x2<=w在圖上對應的是x2->x1的邊權為w的一條邊,而不是x1->x2,這一點不要搞糊塗了。以下是我的差分約束的模板,解決的是《演算法導論》上的例子:
#include
#include
#include
using namespace std;
const int max = 50000;
const int inf = 0x7f7f7f7f;
const int n = 1005;
struct node ;
node node[max];
int n, m;
int adj[n];
int dist[n];
bool vist[n];//標記是否在佇列中,即是否被訪問
int cnt[n];//每個點的訪問次數
int que[n];//用於spfa演算法中的迴圈佇列
bool spfa()
if (++cnt[v] > n)//沒有可行解
return false; }
} }
return true; }
int main()
if(!spfa())
printf("沒有可行解\n");
else
for(int i=1;i<=n;i++)
printf("%d ",dist[i]);
return 0; }
其中檔案in.txt中的內容是:
5 81 2 0
1 5 -1
2 5 1
3 1 5
4 1 4
4 3 -1
5 3 -3
5 4 -3
執行的結果是:0 2 5 4 1 而導論上給出的是-5 -3 0 -1 -4。由引理24.8這是沒問題的,都多了5。其實這是因為我們把dist[1]初始化為了0,如果我們把dist[1]初始化為-5,就可得到導論上的可行解。
關於差分約束的應用可以看一下這道題目:
差分約束 模板
如果需要求的是兩個變數差的最大值,那麼需要將所有不等式轉變成 leq 的形式,建圖後求最短路 如果需要求的是兩個變數差的最小值,那麼需要將所有不等式轉化成 geq 的形式,建圖後求最長路。這是兩個最基本的規則 算是吧 差分約束的精髓就在於建圖,而這玩意兒個人感覺沒什麼好辦法,只能靠不停做題去找到那種...
差分約束模板
如果乙個系統由 n 個變數和 m 個約束條件組成,其中每個約束條件形如 x i x j c k 其中 c k 是常數 可以是負數,也可以是非負數 則稱其為差分約束系統。我們要解決的問題是 求一組解 x 1 a 1,x 2 a 2,x n a n 使得所有的約束條件得到滿足,否則判斷無解。差分約束系統...
差分約束系統 模板
差分約束系統 如果乙個系統由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 全都是...