[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 }

 

posted @ 2019-09-25 00:59  Sword_Art_Online  阅读(117)  评论(0编辑  收藏  举报