問題描述:
給定乙個數軸上的n個區間,要求在數軸上選取最少的點使得第i個區間[ai,bi]裡至少有ci個點。1<=n<=50000, 0<=ai<=bi<=50000, 1<=ci<=bi-ai+1。
差分約束系統求解:
結論:1.如果要求取最小值,則求最長路,將不等式全部化成xi – xj >= k的形式,這樣建立j->i的邊,權值為k的邊,如果不等式組中有xi – xj > k,化為xi – xj >= k+1即可。
2.如果求取的是最大值,則求取最短路,將不等式全部化成xi – xj <= k的形式, 這樣建立j->i的邊,權值為k的邊,特殊處理同上。
思路解析:
1.構造不等式組
記sum[i]表示[0,i]之間選點個數。
對於第i個區間[a,b]需要滿足sum[b+1] - sum[a]≥c。
2.保證sum有意義:0≤sum[i] - sum[i-1]≤1
求該差分約束系統的最小解,轉化為 ≥ 不等式組跑最長路。
**實現:
#include
#include
#include
#include
#include
using
namespace std;
const
int n=
50010
;const
int inf=
1e8;
struct edgee[3
*n];
int inq[n]
,dis[n]
,tot,head[n]
,n;void
add(
int x,
int y,
int w)
void
spfa
(int s)
dis[s]=0
; inq[s]=1
; q.
push
(s);
while
(q.size()
)}}}
}int
main()
for(
int i=mi; i)spfa
(mi)
; cout<
}
總結:差分約束系統求解轉化還是不太理解,先記住結論,再慢慢思考吧(菜 Week 8 作業A 區間選點II
給定乙個數軸上的 n 個區間,要求在數軸上選取最少的點使得第 i 個區間 ai,bi 裡至少有 ci 個點。輸入第一行乙個整數 n 表示區間的個數,接下來的 n 行,每一行兩個用空格隔開的整數 a,b 表示區間的左右端點。1 n 50000,0 ai bi 50000 並且 1 ci bi ai 1...
Week8 作業 A 區間選點 II
給定乙個數軸上的 n 個區間,要求在數軸上選取最少的點使得第 i 個區間 ai,bi 裡至少有 ci 個點 使用差分約束系統的解法解決這道題 input 輸入第一行乙個整數 n 表示區間的個數,接下來的 n 行,每一行兩個用空格隔開的整數 a,b 表示區間的左右端點。1 n 50000,0 ai b...
程式設計思維 week8 作業A 區間選點 II
給定乙個數軸上的 n 個區間,要求在數軸上選取最少的點使得第 i 個區間 ai,bi 裡至少有 ci 個點 使用差分約束系統的解法解決這道題 輸入第一行乙個整數 n 表示區間的個數,接下來的 n 行,每一行兩個用空格隔開的整數 a,b 表示區間的左右端點。1 n 50000,0 ai bi 5000...