從0∼
500000∼
5000
0中選擇盡量少的數字使得n
n組形如「xx到y
y中選擇的數字不少於ckc
k個」的要求全部滿足。設si
si表示從0∼i
0∼i中選擇的數字個數。那麼對於任意乙個要求x,y
,ckx
,y,c
k,都需要滿足sy+
1−sx
≥cks
y+1
−sx
≥ck
,與差分約束十分相像。於是從y
y連向x
x一條長度為ckc
k的邊。同時我們對於數字i
i,肯定是要麼選擇,要麼不選。所以本題中還有兩個隱含條件sk−
sk−1
≥0sk
−sk
−1≥
0,sk−
sk−1
≤1sk
−sk
−1≤
1。對於條件1,可以直接從k−1
k−1向k
k連一條長度為0的邊,對於條件2,變形得sk−
sk−1
≥−1s
k−s
k−1
≥−1,從kk向k
−1k−
1連一條長度為-1的邊。
由於不等式符號全部是大於,所以需要跑最長路。很明顯圖中是不含正環的,所以可以不用判正環。以-1為源點跑spf
aspf
a即可。答案即為dis
[50000]d
is[5
0000
]。但是下標是不可以用負數的。所以可以把所有點的下標+1,變成「從1
∼500011∼
5000
1」中選擇,從0開始跑spf
aspf
a,答案就是dis
[50001]d
is[5
0001
]。
#include
#include
#include
using
namespace std;
const
int n=
50010
;int n,x,y,z,tot,head[n]
,dis[n]
;bool vis[n]
;struct edge
e[n*3]
;void
add(
int from,
int to,
int dis)
void
spfa()
}}}}
intmain()
for(
int i=
1;i<=
50001
;i++
)add
(i-1
,i,0),
add(i,i-1,
-1);
spfa()
;printf
("%d\n"
,dis[
50001])
;return0;
}
差分約束 poj 1201 Interval
差分約束 poj 1201 又是一道vector tle。確實很好的差分約束。很好的差分約束,注意隱含條件 0 d i 1 d i 1 題目保證了沒負圈。include include include using namespace std define n 50005 define inf 100...
POJ 1201 樹狀陣列
給你n個區間,每個區間為 a,b 每個區間取c個數構成乙個集合,求集合最小容量 把區間按b排序,從第乙個區間開始取,從後往前取,這樣盡可能和後面的區間重複 另外如果我們發現當前區間取得個數已經超過了c,那麼只需要讓之前區間換就行,而總數是不變的,所以不用更新答案 求當前區間已經取了多少個數用樹狀陣列...
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 ...