差分約束系統其實就是將不等式組的求解問題轉化為最短路進行求解,所以屬於圖論。但往往抽象出不等式組是不容易的。
差分約束系統入門可看這位大佬的博文:夜深人靜寫演算法(四)
本題大意:n個區間,輸入n行ai,bi,ci,代表在區間[ai, bi]上至少要選擇ci個整數點,可以在區間內任意取ci個不重複的點。求包括所有區間的區間內至少要取多少個整數點。
思路:用d[i]表示從0到i至少要取d[i]個點,可抽象出d[-1]=0,所以[ai, bi]至少要取ci就可以抽象為d[bi] - d[ai-1] >= ci; (閉區間,所以需要減d[ai-1])。下標是從-1開始的,所以寫程式的時候我們需要整體右移一位。
上述是乙個約束條件。又因為每個點要麼取要麼不取,所以得到下面的約束條件:
d[i] - d[i-1] >= 0;
d[i] - d[i-1] <= 1;
不等式既有 >= 又有 <= ,所以需要進行不等式標準化,轉換之後便可以求最短路了,至此,所有約束條件利用完畢。轉換為 <= 是一種做法,轉換為 >= 又是另一種做法,有點細微的區別。
先看下兩種**:
code1:
#include #include #include #include #include using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 50005;
const int maxm = maxn*3;
struct node
edge[maxm];
int no, head[maxn];
int vis[maxn], dis[maxn], cnt[maxn];
queueq;
int low, up;
inline void init()
inline void add(int u, int v, int w)
int spfa(int s, int t)
} }return dis[t];
}int main()
for(int i = low; i <= up; ++i)
add(i, i+1, 0), add(i+1, i, -1);
printf("%d\n", spfa(low, up+1));
return 0;
}
code2:
#include #include #include #include #include using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 50005;
struct node
edge[maxn*3];
queueq;
int n, no, min, max;
int head[maxn], dis[maxn], vis[maxn];
inline void init()
inline void add(int u, int v, int w)
void spfa(int s, int t)
}k = edge[k].next;
} }}int main()
for(int i = min; i < max; ++i)
spfa(max, min);
printf("%d\n", -dis[min]);
return 0;
}
現在來看看兩者的區別:第乙個是通過轉換為 >=不等式組進行建圖的,所以需要求建出圖的最長路徑,需要將dis
初始化為-inf。第二個則是 <=, 求最短路徑, 將dis初始化為inf。還有乙個不同是兩者進行求解路徑的方向是不
同的,乙個(s->t),乙個(t->s),需要選擇正確的求解路徑方向才能得到正確ans。其實選擇求解路徑的方向是根
據建圖的'主方向'確定的,且需要自行判斷哪個求解方向取負才能得到正確答案(個人理解,畢竟這是我做的第乙個差分約束題...),不同的題或許不同。
實際上正解是去求最長路,若干日子之後的新理解:
不管求解兩個變數差的最大值還是最小值,都可以轉為最短路或者最長路去做,注意細節就好。比如用最短路去求,求解最大值時,正是正確方向。求解最小值時,則建的圖恰好是求最長路的反向圖+反向權值,然後再交換始終點即可。
繼續加油~
差分約束系統(poj 1201)
1 內容 是解決多個一元n次不等式組 包含n個變數x1 xn 和m個約束條件,沒個約束條件都是由兩個變數的差值決定的 eg xi xj ck 求一組解x1 a,x2 a2 xn an 2 求解思路 將不等式xi xj ck視為鬆弛操作,dis y dis x ci 進而將問題轉化為兩個點之間的距離的...
POJ 1201(差分約束系統)
poj 1201 1 題意 給出n個區間 ai,bi 要求區間內最少選出ci個整數,求出乙個集合z,滿足n個區間的要求,輸出集合z的最小大小。2 思路 滿足最小要求的差分約束系統,需要求出最長路徑,每個區間都能滿足要求。所以將所有的不等式轉化為ai bi 1 ci的形式,還有乙個隱含條件 0 di ...
poj 1201 差分約束
傳送門 題意 ai到bi間至少有ci個元素,問所有數中至少有多少元素。額。這樣好像說不清楚,我拿樣例說下吧。3到7之間至少有3個元素,8到10之間至少有3個元素,6到8之間至少有1個元素,1到3之間至少有1個元素,10到11之間至少有1個元素。最少情況如下 1 2 3 4 5 6 7 8 9 10 ...