差分約束 區間

2021-10-02 09:00:16 字數 1859 閱讀 4754

給定 n 個區間 [ai

,bi]

和n個整

數c

i[a_i,b_i]和 n 個整數 c_i

[ai​,b

i​]和

n個整數

ci​。

你需要構造乙個整數集合 z,使得∀i∈[1,n],z 中滿足ai≤x≤bi的整數 x 不少於 c

ic_i

ci​個。

求這樣的整數集合 z 最少包含多少個數。

輸入格式

第一行包含整數 n。

接下來n行,每行包含三個整數ai,

bi,c

ia_i,b_i,c_i

ai​,bi

​,ci

​。輸出格式

輸出乙個整數表示結果。

資料範圍

1 ≤n

≤50000

1≤n≤50000

1≤n≤50

000,

0 ≤a

i,bi

≤50000

0≤a_i,b_i≤50000

0≤ai​,

bi​≤

5000

0,$1 ≤c

i≤bi

−ai+

11≤c_i≤b_i−a_i+1

1≤ci​≤

bi​−

ai​+

1輸入樣例:

53 7 3

8 10 3

6 8 1

1 3 1

10 11 1

輸出樣例:

6步驟和上一題一摸一樣。

看到最小值就是最長路。

然後就是提取題目中的不等式,我們這裡利用字首和的思想提出了下面幾個不等式

s

i>=s

i−

1s_i>=s_

si​>=s

i−1​

s i−

si−1

<=1

(si−

1>=s

i−1)

s_i-s_<=1 (s_>=s_i-1)

si​−si

−1​<=1

(si−

1​>=s

i​−1)sb

>=s

a+

cs_b>=s_a+c

sb​>=s

a​+c

s陣列代表我們第i個數字包含了s

is_i

si​個數。

我們做差分約束的時候一定要檢查是否我們能通過乙個源點到達所有其他的點,這裡我們可以發現我們0一定是可以到達所有其他點的。然後我們不等式是否找完了。

這道題一定存在解,所以不存在負環之內的。

#include

using

namespace std;

const

int n=

50001

,m=3

*n;int ne[m]

,cnt,head[m]

,e[m]

,w[m]

,dis[n]

,con[n]

;int n;

bool vis[n]

;void

add(

int a,

int b,

int c)

void

spfa()

}}}}

intmain()

for(

int i=

1;i<=n;

++i)

spfa()

; cout<50001

]

}

區間(差分約束)

題目描述給定 n 個區間 ai,bi 和 n 個整數 ci。你需要構造乙個整數集合 z,使得 i 1,n z 中滿足ai x bi的整數 x 不少於 ci 個。求這樣的整數集合 z 最少包含多少個數。輸入格式 第一行包含整數 n。接下來n行,每行包含三個整數ai,bi,ci。輸出格式 輸出乙個整數表...

差分約束 區間選點

給定乙個數軸上的 n 個區間,要求在數軸上選取最少的點使得第 i 個區間 ai,bi 裡至少有 ci 個點 輸入第一行乙個整數 n 表示區間的個數,接下來的 n 行,每一行兩個用空格隔開的整數 a,b 表示區間的左右端點。1 n 50000,0 ai bi 50000 並且 1 ci bi ai 1...

差分約束 區間選點。c

區間選點 給定乙個數軸上的 n 個區間,要求在數軸上選取最少的點使得第 i 個區間 ai,bi 裡至少有 ci 個點,要求使用差分約束 輸入第一行乙個整數 n 表示區間的個數,接下來的 n 行,每一行兩個用空格隔開的整數 a,b 表示區間的左右端點。1 n 50000,0 ai bi 50000 並...