[bzoj2330][差分约束]糖果

来源:互联网 发布:电子地图数据 编辑:程序博客网 时间:2024/06/02 02:14

Description

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

Input

输入的第一行是两个整数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个小朋友分到的糖果;

Output

输出一行,表示lxhgww老师至少需要准备的糖果数,如果不能满足小朋友们的所有要求,就输出-1。

Sample Input

5 7
1 1 2
2 3 2
4 4 1
3 4 5
5 4 5
2 3 5
4 5 1

Sample Output

11

HINT

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

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

题解

我永远不会说这是一道坑人的题的
这题很强的!1A的都是省队爷

差分题,那么我们列个表
x=1 a=b a>=b+0 且 b>=a+0
x=2 a<=b-1 b>=a+1
x=3 a>=b a>=b+0
x=4 a>=b+1 a>=b+1
x=5 a<=b b>=a+0
另 a>0 a>=1
若进不去d[y]<d[x]+k 则表明d[y]>=d[x]+k 满足上述条件
这就可以看见了。。跑最长路啦
看起来,好水啊,我要1A
结果贡献了一版TLE
要了波数据,发现有一个数据是。。10W个点连成一条链?????
于是,那就入队方式改一改 。从n~1
结果就a了????还是300ms的
枉我T了20多次

#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>#include<cmath>using namespace std;/*x=1 a=b    a>=b+0 且 b>=a+0 x=2 a<=b-1 b>=a+1x=3 a>=b   a>=b+0x=4 a>=b+1 a>=b+1x=5 a<=b   b>=a+0另 a>0 a>=1  若进不去d[y]<d[x]+k 则表明d[y]>=d[x]+k 满足上述条件  */typedef long long LL;struct node{    int x,y,next;    LL c;   }a[510000];int len,last[210000];void ins(int x,int y,LL c){    len++;    a[len].x=x;a[len].y=y;a[len].c=c;    a[len].next=last[x];last[x]=len;}LL d[210000];int ru[210000];bool v[210000];int sta[1110000];int n,k,st,top;int main(){    scanf("%d%d",&n,&k);    len=0;memset(last,0,sizeof(last));    for(int i=1;i<=k;i++)    {        int op;int a,b;        scanf("%d%d%d",&op,&a,&b);        if(op==1){ins(a,b,0);ins(b,a,0);}        if(op==2)        {            if(a==b){printf("-1\n");return 0;}            ins(a,b,1);        }        if(op==3)ins(b,a,0);        if(op==4)        {            if(a==b){printf("-1\n");return 0;}            ins(b,a,1);        }        if(op==5)ins(a,b,0);    }    top=0;    for(int i=1;i<=n;i++)d[i]=1;        for(int i=n;i>=1;i--)sta[++top]=i;    memset(v,true,sizeof(v));    memset(ru,0,sizeof(ru));    bool bk=false;    while(top)    {        int x=sta[top--];        v[x]=false;        for(int k=last[x];k;k=a[k].next)        {            int y=a[k].y;            if(d[y]<d[x]+a[k].c)            {                d[y]=d[x]+a[k].c;                ru[y]++;                if(ru[y]>=n){bk=true;break;}                if(v[y]==false)                {                    v[y]=true;                    sta[++top]=y;                }            }        }    }    if(bk==true)    {        printf("-1\n");    }    else    {        LL ans=0;        for(int i=1;i<=n;i++)ans+=d[i];        printf("%lld\n",ans);    }    return 0;}
原创粉丝点击