BZOJ 2330 SCOI 2011 糖果

2330: [SCOI2011]糖果

Time Limit: 10 Sec  Memory Limit: 128 MB

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

算法讨论:

差分约束裸题。

但是有几个注意的地方:

差分约束可以构建最短路模型,也可以构建最长路模型。

如果有x1 >= 常数。如此的形式,就提醒我们要加超级源点啦。

统计答案的方式。

为了提高SPFA的效率,可以在开始的时候把所有的点都入队。

代码:

#include <cstdlib>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>

using namespace std;
const int N = 100000 + 5;
const int inf = 1000000000;

int n, k, cnt;
int dis[N], head[N], que[N * 10], inque[N];
bool vis[N];
struct Edge {
	int from, to, dis, next;
}edges[N << 2];

void insert(int from, int to, int d) {
	++ cnt;
	edges[cnt].from = from; edges[cnt].to = to; edges[cnt].dis = d;
	edges[cnt].next = head[from]; head[from] = cnt;
}

void init() {
	int x, A, B;
	scanf("%d%d", &n, &k);
	for(int i = 1; i <= k; ++ i) {
		scanf("%d%d%d", &x, &A, &B);
		switch(x) {
			case 1: {	insert(A, B, 0); insert(B, A, 0); break; }
			case 2: { if(A == B) puts("-1"), exit(0); insert(A, B, 1); break; }
			case 3: { insert(B, A, 0); break; }
			case 4: { if(A == B) puts("-1"), exit(0); insert(B, A, 1); break; }
			case 5: { insert(A, B, 0); break; }
		}
	}
	for(int i = 1; i <= n; ++ i) insert(n + 1, i, 1);
}

bool spfa() {
	int h = 1, t = 1;
	vis[n + 1] = true; inque[n + 1] = 1;
	que[h] = n + 1; dis[que[h]] = 0;
	for(int i = 1; i <= n; ++ i) {
		vis[i] = true;
		que[++ t] = i;
		inque[i] = 1;
		dis[i] = -inf;
	}
	while(h <= t) {
		int x = que[h];
		vis[x] = false;
		for(int i = head[x]; i; i = edges[i].next) {
			int v = edges[i].to;
			if(dis[v] < dis[x] + edges[i].dis) {
				dis[v] = dis[x] + edges[i].dis;
				if(!vis[v]) {
					que[++ t] = v;
					inque[v] ++;
					if(inque[v] > n + 1) return false;
					vis[v] = true;
				}
			}
		}
		++ h;
	}
	return true;
}

void work() {
	if(!spfa()) { puts("-1"); return; }
	else {
		long long ans = 0;
		for(int i = 1; i <= n; ++ i)
			ans = (long long) ans + dis[i];
		printf("%lld\n", ans);
	}
}

int main() {
	init();
	work();
	return 0;
}
时间: 2024-08-25 10:10:25

BZOJ 2330 SCOI 2011 糖果的相关文章

BZOJ 2330 SCOI 2011 糖果 差分约束系统

题目大意:幼儿园老师给小盆友们发糖果.有5种要求,问老师最少需要准备多少糖果.如不能满足,输出-1. 思路:裸地差分约束系统,但是正向加边会T,需要反向加边. CODE: #include <queue> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 400010 using namespace std; int

CDOJ 435 (SCOI 2011) 糖果 Label:差分约束系统

糖果 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 131072/131072KB (Java/Others) Submit Status 幼儿园里有NN个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果.但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明不希望小红分到的糖果比他的多,于是在分配糖果的时候,lxhgww需要满足小朋友们的K个要求.幼儿园的糖果总是有限的,lxhgww想知道他至少需

BZOJ 2333 SCOI 2011 棘手的操作 可并堆

做此题的原因 题号美 题目大意 给出一个序列,支持一堆操作(具体看下面).让你维护它. 思路 U x y:我们需要可并堆来将两个堆合并. A1 x v:将这个点从堆中拽出来,改了之后再合并回去. A2 x v:在堆顶打标记. A3:记录一个全局变量记录. F1 x:将这个点到堆顶的链上的所有标记下传,之后返回自己的大小. F2 x:返回堆顶. F3:用一个堆(set也行)维护所有堆顶的元素.需要仔细讨论一下. CODE #define _CRT_SECURE_NO_WARNINGS #inclu

[SCOI 2011]糖果

Description 题库链接 给出 \(N\) 个节点,节点有正点权, \(K\) 个三元组 \((X,A,B)\) 来描述节点点权之间的关系. 如果 \(X=1\) , 表示 \(A\) 的点权必须和 \(B\) 的点权相等: 如果 \(X=2\) , 表示 \(A\) 的点权必须小于 \(B\) 的点权: 如果 \(X=3\) , 表示 \(A\) 的点权必须不小于 \(B\) 的点权: 如果 \(X=4\) , 表示 \(A\) 的点权必须大于 \(B\) 的点权: 如果 \(X=5\

解题:SCOI 2011 糖果

题面 能把差分约束卡死的题,因为正解并不是差分约束 1 #include<queue> 2 #include<cstdio> 3 #include<cctype> 4 #include<cstring> 5 #include<algorithm> 6 using namespace std; 7 const int N=100005; 8 int p[N],noww[2*N],goal[2*N],val[2*N]; 9 int vis[N],in

[BZOJ 2299][HAOI 2011]向量 题解(裴蜀定理)

[BZOJ 2299][HAOI 2011]向量 Description 给你一对数a,b,你可以任意使用(a,b), (a,-b), (-a,b), (-a,-b), (b,a), (b,-a), (-b,a), (-b,-a)这些向量,问你能不能拼出另一个向量(x,y). 说明:这里的拼就是使得你选出的向量之和为(x,y) Input 第一行数组组数t,(t<=50000) 接下来t行每行四个整数a,b,x,y (-2109<=a,b,x,y<=2109) Output t行每行为Y

BZOJ 2330 糖果

Description 幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果.但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明不希望小红分到的糖果比他的多,于是在分配糖果的时候,lxhgww需要满足小朋友们的K个要求.幼儿园的糖果总是有限的,lxhgww想知道他至少需要准备多少个糖果,才能使得每个小朋友都能够分到糖果,并且满足小朋友们所有的要求. Input 输入的第一行是两个整数N,K. 接下来K行,表示这些点需要满足的关系,每行3个数字,X,A

BZOJ 2330: [SCOI2011]糖果 [差分约束系统] 【学习笔记】

2330: [SCOI2011]糖果 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 5395  Solved: 1750[Submit][Status][Discuss] Description 幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果.但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明不希望小红分到的糖果比他的多,于是在分配糖果的时候,lxhgww需要满足小朋友们的K个要求.幼儿园的糖果

bzoj 2330 [SCOI2011]糖果(差分约束系统)

2330: [SCOI2011]糖果 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3574  Solved: 1077[Submit][Status][Discuss] Description 幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果.但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明不希望小红分到的糖果比他的多,于是在分配糖果的时候,lxhgww需要满足小朋友们的K个要求.幼儿园的糖果