給定乙個數軸上的 n 個區間,要求在數軸上選取最少的點使得第 i 個區間 [ai, bi] 裡至少有 ci 個點
input
輸入第一行乙個整數 n 表示區間的個數,接下來的 n 行,每一行兩個用空格隔開的整數 a,b 表示區間的左右端點。1 <= n <= 50000, 0 <= ai <= bi <= 50000 並且 1 <= ci <= bi - ai+1output
輸出乙個整數表示最少選取的點的個數sample input
537
38103
6811
311011
1
sample output
6
差分約束系統 是一種特殊的 n 元一次不等式組,它包含 n個變數以及m個約束條件。
求解差分約束系統,都可以轉化為圖論中單元最短路問題 ,對於差分約束中的每乙個不等式約束?i−?j≤?k 都可以移項變形為 ?i≤?k+?j。我們可以把變數?i看作圖中的乙個結點,對於每個不等式約束?i− ?j≤?k,從節點?到節點?連一條長度為ck的有向邊,於是求解差分約束問題變成了求解最短路問題。
在本題中,要求在數軸上選取最少的點使得第 i 個區間 [ai, bi] 裡至少有 ci 個點。若記???[?]表示數軸上[0,?]之間選點的個數 ,對於第i個區間 [?i,?i] 需要滿足???[bi+1]−???[?i]≥?i。
若sum[i] 為變數,則我們可以得到m個不等式,此題可以用差分約束解決。
將不等式變形可得 sum[bi+1] ≥ ci +sum[ai]。即從節點sum[ai] 到sum[bi+1]有一條有向邊ci。
因此,題目輸入的是一些特定的邊,我們只需要加入這些特定的邊即可。
除了這些特定的邊,還需關注到,區間[0,n] 中 每乙個子區間 [i,i+1] 選的點數大於等於0,而 [i+1,i] 區間不符合規定,不能選點,即為-1。向圖中加入這些邊。
新增完邊之後,使用spfa演算法跑最長路,最終結果即為dis[maxb]。
#include
#include
#include
#include
#define n 50500
using
namespace std;
struct edge
;int head[n]
,dis[n]
,vis[n]
;edge e[
160000];
queue<
int> q;
int index=0;
void
add(
int u,
int v,
int w)
void
sqfa
(int s)}}
}}intmain()
for(
int k=mina; k)sqfa
(mina)
;printf
("%d"
,dis[maxb]);
}
week8 A 區間選點
給定乙個數軸上的 n 個區間,要求在數軸上選取最少的點使得第 i 個區間 ai,bi 裡至少有 ci 個點 使用差分約束系統的解法解決這道題 input 輸入第一行乙個整數 n 表示區間的個數,接下來的 n 行,每一行兩個用空格隔開的整數 a,b 表示區間的左右端點。1 n 50000,0 ai b...
week8 A 區間選點(差分約束系統)
給定乙個數軸上的 n 個區間,要求在數軸上選取最少的點使得第 i 個區間 ai,bi 裡至少有 ci 個點。使用差分約束系統的解法解決這道題!input 輸入第一行乙個整數 n 表示區間的個數,接下來的 n 行,每一行兩個用空格隔開的整數 a,b 表示區間的左右端點。1 n 50000,0 ai b...
week8 A 區間選點 II(差分約束)
一 題目描述 給定乙個數軸上的 n 個區間,要求在數軸上選取最少的點使得第 i 個區間 ai,bi 裡至少有 ci 個點 使用差分約束系統的解法解決這道題 input 輸入第一行乙個整數 n 表示區間的個數,接下來的 n 行,每一行兩個用空格隔開的整數 a,b 表示區間的左右端點。1 n 50000...