SCOI 2011 糖果 SPFA 差分約束

2021-07-22 16:48:10 字數 2683 閱讀 9970

description

幼兒園裡有n個小朋友,lxhgww老師現在想要給這些小朋友們分配糖果,要求每個小朋友都要分到糖果。但是小朋友們也有嫉妒心,總是會提出一些要求,比如小明不希望小紅分到的糖果比他的多,於是在分配糖果的時候,lxhgww需要滿足小朋友們的k個要求。幼兒園的糖果總是有限的,lxhgww想知道他至少需要準備多少個糖果,才能使得每個小朋友都能夠分到糖果,並且滿足小朋友們所有的要求。

input

輸入的第一行是兩個整數n,k。

接下來k行,表示這些點需要滿足的關係,每行3個數字,x,a,b。

如果x=1, 表示第a個小朋友分到的糖果必須和第b個小朋友分到的糖果一樣多;

如果x=2, 表示第a個小朋友分到的糖果必須少於第b個小朋友分到的糖果;

如果x=3, 表示第a個小朋友分到的糖果必須不少於第b個小朋友分到的糖果;

如果x=4, 表示第a個小朋友分到的糖果必須多於第b個小朋友分到的糖果;

如果x=5, 表示第a個小朋友分到的糖果必須不多於第b個小朋友分到的糖果;

output

輸出一行,表示lxhgww老師至少需要準備的糖果數,如果不能滿足小朋友們的所有要求,就輸出-1。

sample input

5 7

1 1 2

2 3 2

4 4 1

3 4 5

5 4 5

2 3 5

4 5 1

sample output

11
hint

【資料範圍】

對於30%的資料,保證 n<=100

對於100%的資料,保證 n<=100000

對於所有的資料,保證 k<=100000,1<=x<=5,1<=a, b<=n

若不懂差分約束先看布局

若問題是像本題一樣乙個點到各個點距離最小

同樣可以將題目中的條件寫成如下形式

xj−xi≤d     //兩個點距離小於d

xj−xi≥d //兩個點距離大於d

我們對於第乙個不等式作如下轉化

xj − xi ≤ d     

=> xj ≤ xi + d

發現它和最長路問題中的三角不等式是一致的:

//d是s到v的最短路 c是u到v的邊權

d(s,v)≥d(s,u)+c(u,v),(u,v)∈e

於是我們可以將

xj - d ≤ xi 這個不等式轉化為

由j到i的一條長度為-d的邊

xj ≥ xi + d 這個不等式轉化為

由i到j的一條長度為d的邊

詳細證明請看:chrt

然後由1作為起點跑spfa(必須為spfa因為dij在有負邊的時候不能使用)

對於題目:若有負權環則輸出-1,否則直接輸出1~n的距離即可

判斷負環

有一種較優秀的方法:對於每乙個點記錄從起點到這個點最長路徑包含的邊的條數。

若邊的條數大於n,易證這個圖有負環。

**

#include 

#include

#include

const

long

long maxn = 200005,maxx = 400005,inf = 10e8;

using

namespace

std;

long

long n,k,e = 1,ans,d[maxx],sum[maxx],head[maxx];

bool inq[maxx];

struct nodeedge[maxx];

queue

long>q;

inline

void addedge(long

long u,long

long v,long

long c);head[u] = e++;

}inline

long

long read()

while('0'

<=ch&&ch <= '9')

return x;

} inline

bool init()

if(x == 2)

if(x == 3)

if(x == 4)

if(x == 5)

}for(long

long i = n;i >= 1;i--) addedge(0,i,1);

return

true;

}inline

bool spfa()}}

}return

true;

}int main()

if(!spfa())

for(long

long i = 1;i <= n;i++) ans += d[i];

printf("%lld",ans);

return

0;}

SCOI2011 糖果 題解

洛谷題面 看到很多題解並沒有講清楚這道題為什麼可以用某些方法,套個板子就沒了。蒟蒻就發一篇題解裝x造福大家吧233 做這道題前,我推薦大家做一下一本通中的1352 例4 13 獎金一題,因為有可能做完了這道題對於你們會有一點啟發。題目分析題目對於小朋友的嫉妒一共有 5 中情況,分別如下 如果 x 1...

題解 SCOI2011 糖果

依舊是比較明顯的差分約束 注意對於五種操作分別對應的連邊方式 然後注意head的初始值判斷,要不然總是超時 今天遇到好幾次了 建圖時加個小剪枝,否則會tle 1 include2 include3 include4 include5 include6 using namespace std 7con...

SCOI2011 糖果 差分約束 判環

scoi2011 糖果 顯然差分約束,根據條件建立所有邊,注意相等建立雙向邊。至於為什麼跑最長路,我認為是只有式子 i 0 1才能建立0到 i i從1到n 的邊,這樣才能把所有點連起來。不過這裡的題解沒有建立0到 i 的所有邊,因為從 0 開始直接spfa 判斷 n 次 會tle,就對每個點用dfs...