BZOJ 2330 糖果题解
差分约束系统 + SPFA
题目传送门: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
(完)