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 }