2330: [SCOI2011]糖果
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 5285 Solved: 1703
[ 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
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
题目大意:
如题。
思路:
查分约束真的是个好东西 0.0
A==B 那么 A - B 和 B - A 都为0
A>=B 相当于 B - A <= 0 B - A 为 0
A<=B 同理
A > B 那么 B - A < 0 因为是整数 所以必然有 B - A <= 1
A < B 同理。 这里判断一下 A = = B 是无解的。
那么建完图之后直接跑最长路就可以。得到的结果加起来。
AC代码:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <queue>
#include <cmath>
using namespace std;
#define maxn 210000
int n,k,num;
int b[maxn],val[maxn],in[maxn],next[maxn],p[maxn],dis[maxn];
bool vis[maxn];
void add(int u,int v,int c)
{
num++;
b[num]=v;
val[num]=c;
next[num]=p[u];
p[u]=num;
}
queue<int>q;
bool spfa()
{
int tot,u;
while(!q.empty())
{
u=q.front();
q.pop();
vis[u]=false;
for(tot=p[u]; tot; tot=next[tot])
{
if(dis[u]+val[tot]>dis[b[tot]])
{
dis[b[tot]]=dis[u]+val[tot];
in[tot]++;
if(in[tot]>n) return false;
if(!vis[b[tot]])
{
vis[b[tot]]=1;
q.push(b[tot]);
}
}
}
}
return true;
}
int main()
{
int u,v,op;
scanf("%d%d",&n,&k);
for(int i=1; i<=k; i++)
{
scanf("%d%d%d",&op,&u,&v);
if(op==1)
{
add(u,v,0);
add(v,u,0);
}
if(op==2)
{
add(u,v,1);
if(u==v)
{
printf("-1\n");
return 0;
}
}
if(op==3)
{
add(v,u,0);
}
if(op==4)
{
add(v,u,1);
if(u==v)
{
printf("-1\n");
return 0;
}
}
if(op==5)
{
add(u,v,0);
}
}
for(int i=1; i<=n; i++)
{
vis[i]=1;
dis[i]=1;
q.push(i);
}
if(!spfa())
{
printf("-1\n");
return 0;
}
long long tmp=0;
for(int i=1; i<=n; i++)
{
tmp+=dis[i];
}
printf("%lld\n",tmp);
return 0;
}