bzoj2330: [SCOI2011]糖果(差分约束)

2330: [SCOI2011]糖果

题目:传送门 

简要题意:

   肉老师有喜事要派糖啦!大家(n个人)都想次糖,可是每个人还都有要求(吃就吃嘛还有要求)。大喜事嘛,肉老师还是会尽力满足地,但是要准备多少糖呢?

   输入k个要求(分别是第x个人对第y个人的要求):

   c=1 x与y吃相同数量的糖果
   c=2 x吃的糖果少于y吃的糖果
   c=3 x吃的糖果不少于y吃的糖果
   c=4 x吃的糖果多于y吃的糖果
   c=5 x吃的糖果不多于y吃的糖果

题解:

   很明显的一眼题啊,约束条件不是都给出来了吗

   c=1 x与y吃相同数量的糖果: a[x]=a[y];-->a[x]>=a[y]+0 a[y]>=a[x]+0
   c=2 x吃的糖果少于y吃的糖果: a[x]<a[y]-->a[y]>=a[x]+1 
   c=3 x吃的糖果不少于y吃的糖果: a[x]>=a[y]-->a[x]>=a[y]+0
   c=4 x吃的糖果多于y吃的糖果: a[x]>a[y]-->a[x]>=a[y]+1
   c=5 x吃的糖果不多于y吃的糖果 a[x]<=a[y]-->a[y]>=a[x]+0

   根据约束条件就可以瞎鸡儿建边跑最长路了啊

   吐槽:一定要倒着进队列,还要开long long

代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 typedef long long LL;
 8 /*
 9     c=1 x与y吃相同数量的糖果: a[x]=a[y];-->a[x]>=a[y]+0 a[y]>=a[x]+0
10   c=2 x吃的糖果少于y吃的糖果: a[x]<a[y]-->a[y]>=a[x]+1 
11   c=3 x吃的糖果不少于y吃的糖果: a[x]>=a[y]-->a[x]>=a[y]+0
12   c=4 x吃的糖果多于y吃的糖果: a[x]>a[y]-->a[x]>=a[y]+1
13   c=5 x吃的糖果不多于y吃的糖果 a[x]<=a[y]-->a[y]>=a[x]+0
14 */
15 struct node
16 {
17     int x,y,next;
18     LL d;
19 }a[510000];int len,last[210000],list[210000];
20 bool v[210000];
21 void ins(int x,int y,LL d)
22 {
23     len++;
24     a[len].x=x;a[len].y=y;a[len].d=d;
25     a[len].next=last[x];last[x]=len;
26 }
27 int ru[210000];LL d[210000];
28 int n,m;
29 int main()
30 {    
31     scanf("%d%d",&n,&m);
32     for(int i=1;i<=m;i++)
33     {
34         int c,x,y;scanf("%d%d%d",&c,&x,&y);
35         if(c==1)ins(x,y,0),ins(y,x,0);
36         if(c==2)ins(x,y,1);
37         if(c==3)ins(y,x,0);
38         if(c==4)ins(y,x,1);
39         if(c==5)ins(x,y,0);
40     }
41     for(int i=1;i<=n;i++)d[i]=1;
42     int head=0;for(int i=n;i>=1;i--)list[++head]=i;
43     memset(v,0,sizeof(v));memset(ru,0,sizeof(ru));
44     while(head!=0)
45     {
46         int x=list[head--];v[x]=true;
47         for(int k=last[x];k;k=a[k].next)
48         {
49             int y=a[k].y;
50             if(d[y]<d[x]+a[k].d)
51             {
52                 ru[y]++;
53                 d[y]=d[x]+a[k].d;
54                 if(ru[y]==n)//判环 
55                 {
56                     printf("-1\n");
57                     return 0;
58                 }
59                 if(v[y])v[y]=false,list[++head]=y;
60             }
61         }
62     }
63     LL ans=0;
64     for(int i=1;i<=n;i++)ans+=d[i];
65     printf("%lld\n",ans);
66     return 0;
67 }
posted @ 2018-03-03 08:44  CHerish_OI  阅读(209)  评论(0编辑  收藏  举报