zoukankan      html  css  js  c++  java
  • BZOJ2330: [SCOI2011]糖果

    【传送门:BZOJ2330


    简要题意:

      有n个小朋友,每一个人都想吃糖,但是有些小朋友之间有攀比风(不要学习),比如说A要比B吃的糖多之类的

      给出k个攀比关系,每个关系输入t,x,y,有5种关系:

      t=1 x与y吃相同数量的糖果

      t=2 x吃的糖果少于y吃的糖果

      t=3 x吃的糖果不少于y吃的糖果

      t=4 x吃的糖果多于y吃的糖果

      t=5 x吃的糖果不多于y吃的糖果

      求出最少的糖果数,使得每个小朋友都有糖吃而且满足k个攀比关系


    题解:

      一眼差分约束

      a[i]为第i个小朋友吃的糖果数

      约束关系:

      t=1 a[x]>=a[y]+0 a[y]>=a[x]+0

      t=2 a[y]>=a[x]+1

      t=3 a[x]>=a[y]+0

      t=4 a[x]>=a[y]+1

      t=5 a[y]>=a[x]+0

      然后跑最长路就可以了

      但是数据有点坑,T了很久,膜了一发hzwer,发现要倒着来进队列,而且要加long long


    参考代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<cmath>
    using namespace std;
    typedef long long LL;
    int list[1100000];
    int ru[210000];
    LL d[210000];
    bool v[210000];
    struct node
    {
        int x,y,next;
        LL d;
    }a[510000];int len,last[210000];
    void ins(int x,int y,LL d)
    {
        len++;
        a[len].x=x;a[len].y=y;a[len].d=d;
        a[len].next=last[x];last[x]=len;
    }
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        len=0;memset(last,0,sizeof(last));
        for(int i=1;i<=m;i++)
        {
            int t,x,y;
            scanf("%d%d%d",&t,&x,&y);
            if(t==1) ins(x,y,0),ins(y,x,0);
            if(t==2) ins(x,y,1);
            if(t==3) ins(y,x,0);
            if(t==4) ins(y,x,1);
            if(t==5) ins(x,y,0);
        }
        for(int i=1;i<=n;i++) d[i]=1;
        int head=0;
        for(int i=n;i>=1;i--) list[++head]=i;
        memset(v,false,sizeof(v));
        memset(ru,0,sizeof(ru));
        while(head!=0)
        {
            int x=list[head--];
            v[x]=true;
            for(int k=last[x];k;k=a[k].next)
            {
                int y=a[k].y;
                if(d[y]<d[x]+a[k].d)
                {
                    d[y]=d[x]+a[k].d;
                    ru[y]++;
                    if(ru[y]==n)
                    {
                        printf("-1
    ");
                        return 0;
                    }
                    if(v[y]==true)
                    {
                        v[y]=false;
                        list[++head]=y;
                    }
                }
            }
        }
        LL ans=0;
        for(int i=1;i<=n;i++) ans+=d[i];
        printf("%lld
    ",ans);
        return 0;
    }

     

  • 相关阅读:
    23种设计模式(12):策略模式
    23种设计模式(11):责任链模式
    23种设计模式(10):命令模式
    23种设计模式(9):访问者模式
    23种设计模式(8):观察者模式
    23种设计模式(7):中介者模式
    23种设计模式(6):模版方法模式
    创建型模式总结
    23种设计模式(5):原型模式
    leetcode6
  • 原文地址:https://www.cnblogs.com/Never-mind/p/8430789.html
Copyright © 2011-2022 走看看