zoukankan      html  css  js  c++  java
  • BZOJ2330 糖果题解 查分约束

    BZOJ 2330 糖果题解

    题目传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2330

    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

    —————————————————————————分割线———————————————————————

     将不等式问题转化为图论问题,这里用SPFA 算法解决最长路。

    裸题一道,不做过多解释。

     

    代码如下:

    /**************************************************************
        Problem: 2330
        User: shadowland
        Language: C++
        Result: Accepted
        Time:220 ms
        Memory:13600 kb
    ****************************************************************/
     
    #include "bits/stdc++.h"
       
    using namespace std ;
    const int maxN = 200010 ;
    typedef long long QAQ ;
       
    struct Path {
            int to , next , w ; 
    }e[ maxN<<2 ];
    int Dis[ maxN ] , In [ maxN ] ,p[ maxN ] ;
    bool visited [ maxN ] ;
       
    int cnt , N , M ;
    QAQ ans ; 
     
    int INPUT()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
     
    void    Add_Edge( const int x , const int y , const int z )
    {
        e[ ++cnt ] . to = y ;
        e[ cnt ] . next = p[ x ] ;
        e[ cnt ] . w = z ;
        p[ x ] = cnt ;
        return ;
    }
    bool    SPFA ( const int S )
    {
        int i , t , temp ;
        queue <int>    Q;
        memset( visited , 0 , sizeof ( visited ) ) ; 
        memset( Dis , 0 , sizeof ( Dis ) ) ; 
        memset( In , 0 , sizeof ( In ) ) ;
        Q.push( S ) ;
        visited[ S ] = true ;
        Dis[ S ] = 0 ;
        while( !Q.empty( ) ) 
        {
            t = Q.front( ) ;Q.pop( ) ;visited[ t ] = false ;
            for( i=p[t] ; i ; i = e[ i ] . next )
            {
                temp = e[ i ].to;
                if(Dis[ temp ] < Dis[ t ] + e[ i ].w)
                {
                    Dis[ temp ] = Dis[ t ] + e[ i ] . w ;
                    if( !visited[ temp ] )
                    {
                        Q.push( temp ) ;
                        visited[ temp ] = true ;
                        if( ++In[temp] > N ) return false ;
                    }
                       
                }
            }
        }
        return true ;
    }
    int main ( ) {
             N = INPUT ( ) ;
             M = INPUT ( ) ;
             for ( int i=1 ; i<=M ; ++i ) {
                     int _ , x , y ;
                     _ = INPUT ( ) ;x = INPUT ( ) ;y = INPUT ( ) ;
                     if ( _ ==1 ){
                             Add_Edge ( x , y , 0 ) ;
                             Add_Edge ( y , x , 0 ) ;
                     }else
                     if ( _==2 ) {
                             if ( x==y ) goto Fail ;else
                             Add_Edge ( x , y , 1 ) ;
                     }else
                     if ( _==3 ) {
                             Add_Edge ( y , x , 0 ) ;
                     }else
                     if ( _==4 ) { 
                             if ( x==y ) goto Fail ; else
                             Add_Edge ( y , x , 1 ) ;
                     }else
                     {
                             Add_Edge ( x , y , 0 ) ;
                     }
             }
             for ( int i=N ; i>=1 ; --i ) 
                     Add_Edge ( 0 , i , 1 ) ;
             if ( !SPFA ( 0 ))goto Fail ;
             for ( int i=1 ; i<=N ; ++i ) {
                     ans += Dis [ i ] ;
             }
             printf ( "%lld
    " , ans ) ;
             goto End ;
             Fail:
             printf ( "-1
    " ) ;
             End:
             return 0 ;
    }

    2016-09-14 18:14:40

     (完)

     

     

     

  • 相关阅读:
    JAVA线程池
    数据库三范式和反三范式
    nvm切换node的版本
    vue源码解析一
    css实现气泡样式
    openlayer 地图实现圈选框选清楚 选择地图区域
    vs code开发常用插件
    记录几个好用的工具
    03 使用css改变页面样式
    02 常用的html元素
  • 原文地址:https://www.cnblogs.com/shadowland/p/5872586.html
Copyright © 2011-2022 走看看