[SCOI2011]糖果
作者:互联网
【题目描述】:
幼儿园里有N个小朋友,1xhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果。但是小朋友们也有嫉妒心,总是会提出些要求,比如小明不希望小红分到的糖果比他的多,于是在分配糖果的时候lkhgww需要满足小朋友们的K个要求。幼儿园的糖果总数是有限的,1xhgww想知道他至少需要准备多少个糖果,才能使得每个小朋友都能够分到糖果,并且满足小朋友们所有的要求。
PS:出题人/搬题人太毒,建图顺序不对会导致#5会TLE/WA。。。
【输入描述】:
输人的第一行是两个整数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
【时间限制、数据范围及描述】:
时间:1s 空间:128M
对于30%的数据,保证N<=100。
对于100%的数据,保证N<=100,000。
对于所有的数据,保证K<=100,000;1<=X<=5;1<=A,B<=N。
分析:
本题显然还是一道差分约束的模板题,只要会差分约束应该不难。所以不多讲解,直接上代码。
CODE:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<queue> 5 #include<cstring> 6 using namespace std; 7 int n,k,tot; 8 long long ans; 9 int head[300005],next[300005],to[300005],w[300005],dis[300005],used[300005]; 10 bool vis[300005]; 11 queue<int>q; 12 inline int get(){ 13 char c=getchar(); 14 int res=0; 15 while (c<'0'||c>'9') c=getchar(); 16 while (c>='0'&&c<='9'){ 17 res=(res<<3)+(res<<1)+c-'0'; 18 c=getchar(); 19 } 20 return res; 21 } 22 void add(int u,int v,int c){ 23 to[++tot]=v; 24 next[tot]=head[u]; 25 head[u]=tot; 26 w[tot]=c; 27 } 28 int main(){ 29 n=get(); 30 k=get(); 31 while(k--){ 32 int u,v,c; 33 c=get(),u=get(),v=get(); 34 if(c==1){ 35 add(u,v,0); 36 add(v,u,0); 37 } 38 else if(c==2){ 39 if(u==v){ 40 printf("-1\n"); 41 return 0; 42 } 43 add(u,v,1); 44 } 45 else if(c==3){ 46 add(v,u,0); 47 } 48 else if(c==4){ 49 if(v==u){ 50 printf("-1\n"); 51 return 0; 52 } 53 add(v,u,1); 54 } 55 else if(c==5)add(u,v,0); 56 } 57 for(int i=n;i>=1;i--){ 58 add(0,i,1); 59 } 60 vis[0]=1,q.push(0); 61 while(!q.empty()){ 62 int u=q.front(); 63 q.pop(); 64 vis[u]=0; 65 if(used[u]==n-1){ 66 printf("-1\n"); 67 return 0; 68 } 69 used[u]++; 70 for(int i=head[u];i;i=next[i]){ 71 if(dis[to[i]]<dis[u]+w[i]){ 72 dis[to[i]]=dis[u]+w[i]; 73 if(!vis[to[i]]){ 74 vis[to[i]]=1; 75 q.push(to[i]); 76 } 77 } 78 } 79 } 80 for(int i=1;i<=n;i++){ 81 ans+=dis[i]; 82 } 83 printf("%lld\n",ans); 84 return 0; 85 }
标签:分到,int,小朋友,include,糖果,300005,SCOI2011 来源: https://www.cnblogs.com/kanchuang/p/11125731.html