題目重述
思路概述
題目原始碼(c++)
差分約束系統,是一種不等式系統,形式比較固定。具體的形式如下:
對於差分約束系統一般有兩種形式:
1、xi-xj<=ck,求解的上限–>即xi-xj=ck的情況
2、xi-xj>=ck,求解的下限–>即xi-xj=ck的情況
對這兩種情況,可以使用相同的轉換思路,將xj移到不等式右側後可以得到xi<=ck+xj求上限和xi>=ck+xj求下限,熟悉最短路的鬆弛操作的同學就會發現,這個式子和鬆弛後得到的條件是一模一樣的,也就是:將xi視為dis[i],將xj視為dis[j],ck視為邊長,利用最短路演算法來求解差分約束系統
進過轉換後,具體的實現思路如下:
1、將每乙個約束條件(例xi-xj<=ck)轉換成一條有向邊(j,i,ck),並存入圖中
2、對生成好的圖跑最短路演算法(由於ck的值可能為負值,採用spfa演算法比較合理)
3、令dis[1]=0,得到的xi=dis[i]即為差分約束系統的一組解
兩種特殊情況的處理:
1、出現負環,出現負環,說明某些點的dis[i]=-inf,則表示式變為xi-x1<=-inf,我們無法找到這樣的乙個解,說明該差分約束系統無解。
2、出現某點不可達,說明某點滿足dis[i]=inf,則表示式變為xi-x1<=inf,該條件在任何取值下都滿足,說明差分約束系統對xi無明確約束,可以取任何值。
給定乙個數軸上的 n 個區間,要求在數軸上選取最少的點使得第 i 個區間 [ai, bi] 裡至少有 ci 個點
輸入第一行乙個整數 n 表示區間的個數,接下來的 n 行,每一行兩個用空格隔開的整數 a,b 表示區間的左右端點。1 <= n <= 50000, 0 <= ai <= bi <= 50000 並且 1 <= ci <= bi - ai+1。
輸入樣例
5輸出乙個整數表示最少選取的點的個數3 7 3
8 10 3
6 8 1
1 3 1
10 11 1
輸出樣例:
給定幾個區間,每個區間內要求有n個點,求出能夠滿足條件的選擇的最少點。由於題目要求最少點滿足選點條件,看到這個題目的第一反應可能會想到是一道貪心演算法的題目,且這道題和貪心問題裡的區間選點問題十分相似。
但如果使用貪心演算法,對多個點的貪心並不容易實現,可能需要比較複雜的模擬。這裡介紹一種利用差分約束求解這道題的做法。
我們使用sum[i]來表示從源點0開始,選的點個數。(雖然題目中說明點的範圍是1-5e4,但如果從sum[1]開始我們是無法衡量出1號點是否被選中,所以使用0號點開始操作比較方便)
條件a b a(a到b閉區間內選擇a個點)可以轉換為sum[b]-sum[a-1]>=a,通過模擬發現該型別的條件與上述的差分約束系統十分相似,可以使用差分約束來巧妙求解。
但是只有這些邊條件是不夠的,因為實際意義,每個點只能是選擇或者不選擇兩個可能,我們可以得出如下的條件0<=sum[i]-sum[i-1]<=1,對圖中的每兩點進行連線邊即可。由於求的是最少點,所以需要將所有約束條件轉換成xi-xj>=ck的形式。在轉換完成後的圖中跑一遍最長路即可得出解。
題目所求的最少點,也就是sum[maxi]的值。
#include
#include
#include
using
namespace std;
const
int n=
5e4+5;
struct edge
edges[n]
;int edge_cnt;
int point_cnt;
int head[n]
;void
init()
void
add(
int x,
int y,
int value)
int vis[n]
;int dis[n]
;queue<
int> q;
void
spfa()
vis[0]
=1,dis[0]
=0; q.
push(0
);while
(!q.
empty()
)}}}
}int
main()
point_cnt=max_number;
for(
int i=
1;i<=point_cnt;i++
)spfa()
; cout<
;return0;
}
差分約束和dp和最短路
我發現學的越深入,各個知識點之間的關係真的就是越緊密,我希望有一天我能學習完所有的演算法,站在演算法的頂端俯瞰各個演算法之間的聯絡,感受演算法之美,感受邏輯之美,想想那時候是多麼的驕傲和自豪啊。很久之前做過的一道題目,當時做的時候是跟著老師的思路來做的,當時並沒有多大的啟發,但是後邊我在看一遍的時候...
差分約束系統 變相的最短路
之前沒有細看,想不明白這個問題怎麼和最短路扯上關係,細細看了看,也沒明白,原因是在看dijk演算法的時候就沒好搞明白它的 實現,以至於這個問題模擬到最短路實現的時候一臉懵,還去瞅了瞅三角不等式是什麼東西,簡單來說,難就難在圖的構造上面,構造好圖之後就是模板,就是之前的內容了,一起看看這個東西吧,on...
K Candies 差分約束 最短路)
有n個孩子,m個關係 關係分別有3個數u,v,w。代表v的糖果數不能多於u w個,也就是dis v dis u w 這就轉換成 if dis v dis u w dis v dis u w.1 spfa stack include include include include includecon...