POJ1201 Intervals 差分約束

2021-09-11 01:25:52 字數 1866 閱讀 4109

從0

∼50000

0\sim50000

0∼5000

0中選擇盡量少的數字使得n

nn組形如「x

xx到y

yy中選擇的數字不少於c

kc_k

ck​個」的要求全部滿足。

設s

is_i

si​表示從0∼i

0\sim i

0∼i中選擇的數字個數。那麼對於任意乙個要求x,y

,c

kx,y,c_k

x,y,ck

​,都需要滿足sy+

1−sx

≥c

ks_-s_x\geq c_k

sy+1​−

sx​≥

ck​,與差分約束十分相像。於是從y

yy連向x

xx一條長度為c

kc_k

ck​的邊。

同時我們對於數字i

ii,肯定是要麼選擇,要麼不選。所以本題中還有兩個隱含條件sk−

sk−1

≥0

s_k-s_\geq 0

sk​−sk

−1​≥

0,sk−s

k−1≤

1s_k-s_\leq 1

sk​−sk

−1​≤

1。對於條件1,可以直接從k−1

k-1k−

1向kk

k連一條長度為0的邊,對於條件2,變形得sk−

sk−1

≥−

1s_k-s_k-1\geq -1

sk​−sk

​−1≥

−1,從k

kk向k−1

k-1k−

1連一條長度為-1的邊。

由於不等式符號全部是大於,所以需要跑最長路。很明顯圖中是不含正環的,所以可以不用判正環。以-1為源點跑spf

aspfa

spfa

即可。答案即為dis

[50000

]dis[50000]

dis[50

000]

。但是下標是不可以用負數的。所以可以把所有點的下標+1,變成「從1

∼50001

1\sim50001

1∼5000

1」中選擇,從0開始跑spf

aspfa

spfa

,答案就是dis

[50001

]dis[50001]

dis[50

001]

#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 ...