題目大意如此:
現在有乙個序列,我們用n個形如,ai,bi,ci的式子去描述它,表示序列中必須至少有大於等於ai並且小於等於bi的整數有ci個。要求輸出序列長度最小為多少。
n的範圍為50000,0 < a < b < 50000。
這個題我們一看就知道是差分約束(霧)。
我們令s[i]表示0到i的整數有多少個。
所以我們可以清楚地寫出下列式子:
s[b]-s[a-1]>=c
s[i]-s[i-1]<=1(i取任意)
s[i]-s[i-1]>=0(i取任意)
然後我們知道在做最短路的時候(只會spfa的我- -)
有乙個三角式子dis[v] <= dis[u]+w(u,v)
我們變一下dis[v]-dis[u] <= w(u,v)是不是很像上面那個。
我們根據這樣建邊,也就是b到a-1建一條權值為-c的邊。
i-1到i建一條權值為1的邊。i到i-1建一條權值為0的邊。
然後我們弄乙個虛擬點s向每個點建一條權值為0的邊。
這樣以虛擬點s為源點跑spfa,那麼就可以得到答案啦。
是不是特別簡單。
當然這道題說明了一定有解,不然一定注意要判斷是否存在負環,如果有說明無解。
**如下:
#include
#include
#include
#include
#define n 50010
#define inf 0x3f3f3f3f
using
namespace
std;
int n,num,head[n];
struct edge;
edge e[10*n];
void adde(int i,int j,int w)
int vis[n],dis[n],s;
void spfa()}}
}}int a,b,c;
int main()
for(int i=st;i<=ed;i++)
spfa();
// for(int i=st;i<=ed;i++)//這裡可以輸出具體方案
// if(dis[i]-dis[i-1]==1)printf("%d ",i);
printf("%d\n",dis[ed]-dis[st-1]);//注意是st-1
return
0;}
POJ 1201 差分約束系統
差分約束系統其實就是將不等式組的求解問題轉化為最短路進行求解,所以屬於圖論。但往往抽象出不等式組是不容易的。差分約束系統入門可看這位大佬的博文 夜深人靜寫演算法 四 本題大意 n個區間,輸入n行ai,bi,ci,代表在區間 ai,bi 上至少要選擇ci個整數點,可以在區間內任意取ci個不重複的點。求...
差分約束系統(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 ...