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\n" , ans ) ;
         goto End ;
         Fail:
         printf ( "-1\n" ) ;
         End:
         return 0 ;
}

 

2016-09-14 18:14:40

 

 (完)

 

 

 

posted @ 2016-09-14 18:15  SHHHS  阅读(479)  评论(0编辑  收藏  举报