bzoj 2330: [SCOI2011]糖果
2330: [SCOI2011]糖果
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 4112 Solved: 1264
[Submit][Status][Discuss]
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
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
Source
差分约束裸题。
不会差分约束的话可以戳这里
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 5 template <class T> inline void read(T &x) { 6 static char c; 7 while (!isdigit(c = getchar())); 8 for (x = 0; isdigit(c); c = getchar()) x = x * 10 + c - 48; 9 } 10 11 const int MAXN = 1e5 + 10; 12 13 struct edge { int to, next, w; } e[MAXN << 2]; 14 15 int N, K; 16 int st[MAXN]; 17 int f[MAXN], vis[MAXN], in[MAXN]; 18 queue<int> Q; 19 20 inline void addedge(int u, int v, int w) 21 { 22 static int cnt = 0; 23 e[++cnt] = (edge) {v, st[u], w}; 24 st[u] = cnt; 25 } 26 27 bool SPFA() 28 { 29 memset(f, 0xef, sizeof f); 30 f[0] = 0; 31 Q.push(0); 32 while (Q.size()) { 33 int x = Q.front(); Q.pop(); 34 vis[x] = 0; 35 for (int i = st[x]; i; i = e[i].next) { 36 int v = e[i].to; 37 if (f[v] < f[x] + e[i].w) { 38 f[v] = f[x] + e[i].w; 39 if (in[v] ++ > N) { 40 return 0; 41 } 42 if (!vis[v]) { 43 vis[v] = 1; 44 Q.push(v); 45 } 46 } 47 } 48 } 49 return 1; 50 } 51 52 int main() 53 { 54 read(N); read(K); 55 for (int i = 1; i <= K; ++ i) { 56 int k, a, b; 57 read(k), read(a), read(b); 58 if (k == 1) { addedge(a, b, 0); addedge(b, a, 0); } 59 if (k == 2) { addedge(a, b, 1); } 60 if (k == 3) { addedge(b, a, 0); } 61 if (k == 4) { addedge(b, a, 1); } 62 if (k == 5) { addedge(a, b, 0); } 63 } 64 for (int i = N; i; -- i) { 65 addedge(0, i, 1); 66 } 67 if (!SPFA()) 68 puts("-1"); 69 else { 70 LL ans = 0; 71 for (int i = 1; i <= N; ++ i) ans += f[i]; 72 printf("%lld\n", ans); 73 } 74 }
__Stay hungry, Stay foolish.