題目描述
幼兒園裡有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
樣例輸入
5 7
1 1 2
2 3 2
4 4 1
3 4 5
5 4 5
2 3 5
4 5 1
樣例輸出
11分析:
分析:
裸題定義:
差分約束系統,是求解關於一組變數的特殊不等式組的方法
如果乙個系統是由n個變數和m個約束條件組成,
其中每個約束條件形如xj-xi<=bk,則稱其為差分約束條件
解法 求解差分約束系統,
可以轉化為凸輪的單元最短路徑問題
觀察xj-xi<=bk
移項的xj<=xi+bk
很像最短路形式
這樣m條限制就轉化成了m條連線x,y且權值是b的邊(單向邊)
對這個圖執行spfa
最終的dis[i]即為一組可行解
都是合法解
存在負環則無合法解,存在不可到達的點,則存在無限解
spfa怎麼判斷負環呢
有兩種方法:
1)spfa的dfs形式,判斷條件是存在一點在一條路徑上出現多次
2)spfa的bfs形式,判斷條件是存在一點入隊次數大於總頂點數
看了一些前輩的題解
發現這道題好像非常的毒
首先我們需要計算的是最小糖果數
所以要跑乙個最大路
開3*n的邊
連邊:單向邊
建立乙個超級源點0
0向n~1連邊(注意順序,不然會t)
注意in的維護
開ll在bzoj上就是wa,莫名其妙
辣雞**oj
這裡寫**片
#include
#include
#include
#define ll long long
using
namespace
std;
const
int n=100100;
int n,m;
struct node;
node way[n*3];
int tot=0,st[n],in[n],q[n],tou,wei,dis[n];
bool p[n];
void add(int u,int w,int z)
void spfa()
if (p[y])}}
p[r]=1;
}while (tou0;
for (int i=1;i<=n;i++) ans+=(ll)dis[i];
printf("%lld",ans);
}int main()
else
if (opt==2)
else
if (opt==3)
else
if (opt==4)
else
}for (int i=n;i;i--) add(0,i,1); //ss
spfa();
return
0;}
bzoj2330 差分約束 糖果
description 幼兒園裡有n個小朋友,lxhgww老師現在想要給這些小朋友們分配糖果,要求每個小朋友都要分到糖果。但是小朋友們也有嫉妒心,總是會提出一些要求,比如小明不希望小紅分到的糖果比他的多,於是在分配糖果的時候,lxhgww需要滿足小朋友們的k個要求。幼兒園的糖果總是有限的,lxhgw...
BZOJ 2330 差分約束系統
差分約束系統是用最短路的三角不等式來得到題目中給定的不等式的一組解,具體來說,最短路中的不等式為if dis v dis u len p dis v dis u len p 假設題目中給定不等式a b 5,那麼轉換的不等式即為if dis a dis b 5 dis a dis b 5,這樣就把數學...
BZOJ 2330 差分約束系統
傳送門 差分約束這裡做個簡單介紹 形如 x i x j d 的不等式,可以聯想到我們求最短路時 d v d u len 則上式可以變形為 x i x j d 即連一條j i的長度為d的邊並跑最長路,dis i 則是滿足條件的最小解 因為上面等式採用的 號,所以求出的時最小解,同理當變形為 x j x...