CSP 差分約束系統和最短路求解

2021-10-04 23:39:23 字數 2496 閱讀 9774

題目重述

思路概述

題目原始碼(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...