首页 > 代码库 > P3275 [SCOI2011]糖果

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 71 1 22 3 24 4 13 4 55 4 52 3 54 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 node22 {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 } 

 

P3275 [SCOI2011]糖果