scoi 糖果
題目描述
幼兒園裡有n個小朋友,lxhgww老師現在想要給這些小朋友們分配糖果,要求每個小朋友都要分到糖果。但是小朋友們也有嫉妒心,總是會提出一些要求,比如小明不希望小紅分到的糖果比他的多,於是在分配糖果的時候,lxhgww需要滿足小朋友們的k個要求。幼兒園的糖果總是有限的,lxhgww想知道他至少需要準備多少個糖果,才能使得每個小朋友都能夠分到糖果,並且滿足小朋友們所有的要求。
輸入輸出格式
輸入格式:
輸入的第一行是兩個整數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個小朋友分到的糖果;
輸出格式:
輸出一行,表示lxhgww老師至少需要準備的糖果數,如果不能滿足小朋友們的所有要求,就輸出-1。
input sample
5 71 1 2
2 3 2
4 4 1
3 4 5
5 4 5
2 3 5
4 5 1
output sample
11省選題裡面比較簡單適合練手的差分約束題。 切入點在於對於每個命令其實都可以轉化成乙個不等式。
比如當 x=1時 0<=(a-b)<=0 我們在這裡可以定義 dis(a)為小朋友拿的糖果,那麼可以有以下轉換
對於 x=1 dis(a)+0<=dis(b) && dis(b)+0<=dis(a)
對於 x=2 dis(a)+1<=dis(b)
對於 x=3 dis(b)+0<=dis(a)
對於 x=4 dis(b)+1<=dis(a)
對於 x=5 dis(a)+0<=dis(b)
可以發現其實這題在轉換為圖以後就是在求圖中的最長路,因為我們在這條路徑上鬆弛時會把路徑從小變大以符合題目要求的最小條件,也就是至少有多少糖果。並且注意到每個人至少有乙個糖果,那麼我們定義超級源點 0,並且和每個點都接上一條權為1的邊,以保證最長路至少對於每個點為1. 這題的正權環或者正權自環就會導致題目無解,因為你會發現 這其實是在要求 dis(a)>dis(b) 同時 dis(b)>dis(a),導致這個環會無限跑下去。
這題的小tips 是得反著和超級源點連邊…因為聽說原資料有一條巨長的鏈卡spfa,然後對於 x=2或x=4,如果a==b 那麼說明會有自環,自己一直比自己大 就會無限加下去。
code
#include #include #include #include #include #define maxn 300005
using namespace std;
int n, m;
int u[maxn],v[maxn],w[maxn],nex[maxn],first[maxn];
int tot;
int vis[maxn],d[maxn],cnt[maxn];
void add(int x,int y,int z)
int gi()
inline bool spfa()
q.push(v[i]);}}
} }return 1;
}int main()
if(z==2)
if(!spfa())
long long ans=0;
for(i=1;i<=n;i++)
ans+=d[i];
cout<}```
SCOI 2011 糖果 SPFA 差分約束
description 幼兒園裡有n個小朋友,lxhgww老師現在想要給這些小朋友們分配糖果,要求每個小朋友都要分到糖果。但是小朋友們也有嫉妒心,總是會提出一些要求,比如小明不希望小紅分到的糖果比他的多,於是在分配糖果的時候,lxhgww需要滿足小朋友們的k個要求。幼兒園的糖果總是有限的,lxhgw...
差分約束 糖果
幼兒園裡有 n 個小朋友,老師現在想要給這些小朋友們分配糖果,要求每個小朋友都要分到糖果。但是小朋友們也有嫉妒心,總是會提出一些要求,比如小明不希望小紅分到的糖果比他的多,於是在分配糖果的時候,老師需要滿足小朋友們的 k 個要求。幼兒園的糖果總是有限的,老師想知道他至少需要準備多少個糖果,才能使得每...
差分約束 糖果
幼兒園裡有 nn 個小朋友,老師現在想要給這些小朋友們分配糖果,要求每個小朋友都要分到糖果。但是小朋友們也有嫉妒心,總是會提出一些要求,比如小明不希望小紅分到的糖果比他的多,於是在分配糖果的時候,老師需要滿足小朋友們的 kk 個要求。幼兒園的糖果總是有限的,老師想知道他至少需要準備多少個糖果,才能使...