zoukankan      html  css  js  c++  java
  • bzoj2330: [SCOI2011]糖果 (利用差分约束系统将之转换成最长路的问题)

    题目

    2330: [SCOI2011]糖果
    时间限制: 10 Sec  内存限制: 128 MB
    题目描述
    幼儿园里有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。
    样例输入
    5 7
    1 1 2
    2 3 2
    4 4 1
    3 4 5
    5 4 5
    2 3 5
    4 5 1
    样例输出
    11
    提示
    【数据范围】
        对于30%的数据,保证 N<=100
        对于100%的数据,保证 N<=100000
    对于所有的数据,保证 K<=1000001<=X<=51<=A, B<=N
    View Code

     这道题的解法呢正如标题所写,可以发现小朋友的关系可以构成不等式,所以我们可以把这些条件利用差分约束系统将其转化为最长路,然后用spfa跑一遍就行了。

    附上一个链接:

    http://wenku.baidu.com/view/c37d3486bceb19e8b8f6baae.html

    #include<stdio.h>
    #include<string.h>
    int h,t,l[101010],dd[500000],ccc[101010],cnt,j,n,m,x,y,xx,hh[101010],w,z;
    long long ans;
    bool d[101010];
    struct node
    {
     int next,v,zz;
    }b[500000];
    void add(int aa,int bb,int cc)
    {
     b[++cnt].v=bb;
     b[cnt].next=hh[aa];
     b[cnt].zz=cc;
     hh[aa]=cnt;
    }
    bool spfa(int q)
    {
     int i;
     memset(d,0,sizeof(d));
     h=0,t=0;
     l[q]=0;d[q]=true;
     while(1)
     {
      if(h>t)break;
       
      for(i=hh[q];i!=0;i=b[i].next)
      {
        z=b[i].v;
        w=b[i].zz;
        if(l[q]+w>l[z]){
           l[z]=l[q]+w;
           if(d[z])continue;
           if(++ccc[z]>n)return false;
           dd[++t]=z;
           d[z]=true;
        }   
      }
      d[q]=false;
        q=dd[++h];
     }
     return true;   
    }
    int main()
    {
     int i;
     scanf("%d %d",&n,&m);
     for(i=1;i<=m;i++)
        {
            scanf("%d%d%d",&xx,&x,&y);
            if(xx==1){add(x,y,0);add(y,x,0);}
            else if(xx==2)if(x==y){printf("-1
    ");return 0;}else add(x,y,1);
            else if(xx==3)add(y,x,0);
            else if(xx==4)if(x==y){printf("-1
    ");return 0;}else add(y,x,1);
            else if(xx==5)add(x,y,0);
        }
     for(i=n;i>=1;i--)
      add(0,i,1);
     if(!spfa(0)){printf("-1
    ");return 0;} 
     for(i=1;i<=n;i++)
      ans+=l[i];
     printf("%lld",ans);
      
     return 0;
    } 
    
    

      

  • 相关阅读:
    Scrum与看板区别
    Android中的Apk的加固(加壳)原理解析和实现
    规模化敏捷开发的10个最佳实践
    TDD、BDD、ATDD、DDD 软件开发模式
    如何解决秒杀的性能问题和超卖的讨论
    mongo数据库的各种查询语句示例
    linux if -d -e -f表达的意思
    prometeus, grafana部署以及监控mysql
    2019年目标
    nginx 动态添加ssl模块
  • 原文地址:https://www.cnblogs.com/haizhe/p/5869715.html
Copyright © 2011-2022 走看看