P3275 [SCOI2011]糖果

题目描述

幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果。但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明不希望小红分到的糖果比他的多,于是在分配糖果的时候,lxhgww需要满足小朋友们的K个要求。幼儿园的糖果总是有限的,lxhgww想知道他至少需要准备多少个糖果,才能使得每个小朋友都能够分到糖果,并且满足小朋友们所有的要求。

输入输出格式

输入格式:

 

输入的第一行是两个整数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。

 

输入输出样例

输入样例#1:
5 7
1 1 2
2 3 2
4 4 1
3 4 5
5 4 5
2 3 5
4 5 1
输出样例#1:
11

说明

【数据范围】

对于30%的数据,保证 N<=100

对于100%的数据,保证 N<=100000

对于所有的数据,保证 K<=100000,1<=X<=5,1<=A, B<=N

 

话说出题人真是用(sang)心(xin)良(bing)苦(kuang)

差分约束卡SPFA。。

我还能说什么。。

=.=、、、、、、

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<queue>
 6 #include<algorithm>
 7 #include<cstdlib>
 8 #define lli int 
 9 using namespace std;
10 const int MAXN=233333;
11 inline void read(int &n)
12 {
13     char c='+';int x=0,flag=1;
14     while(c<'0'||c>'9')
15     {c=getchar();if(c=='-')flag=-1;}
16     while(c>='0'&&c<='9')
17     {x=x*10+c-48;c=getchar();}
18     n=(x*flag);
19 }
20 int n,m;
21 struct node
22 {
23     int u,v,w,nxt;
24 }edge[MAXN];
25 int head[MAXN];
26 int num=1;
27 inline void no_ans()
28 {
29     printf("-1");
30     exit(0);
31 }
32 inline void add_edge(int x,int y,int z)
33 {
34     edge[num].u=x;
35     edge[num].v=y;
36     edge[num].w=z;
37     edge[num].nxt=head[x];
38     head[x]=num++;
39 }
40 int dis[MAXN];
41 int vis[MAXN];
42 int happen[MAXN];
43 inline bool SPFA(int p)
44 {
45     if(happen[p]>n)
46     no_ans();
47     vis[p]=1;
48     for(register int i=head[p];i!=-1;i=edge[i].nxt)
49     {
50         if(dis[edge[i].v]>dis[edge[i].u]+edge[i].w)
51         {
52             dis[edge[i].v]=dis[edge[i].u]+edge[i].w;
53             happen[edge[i].v]++;
54             if(vis[edge[i].v]||!SPFA(edge[i].v))
55                 return false;
56         }
57     }
58     vis[p]=0;
59     return true;
60 }
61 int main()
62 {
63     memset(dis,0x3f,sizeof(dis));
64     memset(head,-1,sizeof(head));
65     read(n);read(m);
66     for(register int i=n;i>=1;--i)
67         add_edge(0,i,-1);
68     for(register int i=1;i<=m;++i)
69     {
70         int how,a,b;
71         read(how);read(a);read(b);
72         if(how==1)
73         {
74             add_edge(b,a,0);add_edge(a,b,0);
75         }
76         else if(how==2)
77         {
78             if(a==b)no_ans();
79             add_edge(a,b,-1);
80         }
81         else if(how==3)
82             add_edge(b,a,0);
83         else if(how==4)
84             add_edge(b,a,-1);
85         else if(how==5)
86             add_edge(a,b,0);
87     }
88     dis[0]=0;
89     long long int ans=0;
90     if(SPFA(0))
91     {
92         for(register int i=1;i<=n;++i)
93             ans-=dis[i];
94     }
95     else no_ans();
96     printf("%lld",ans);
97     return 0;
98 } 

 

posted @ 2017-07-05 19:10  自为风月马前卒  阅读(441)  评论(0编辑  收藏  举报

Contact with me