现在的位置: 首页 > 综合 > 正文

【HDU】1531 King 差分约束

2017年11月20日 ⁄ 综合 ⁄ 共 1598字 ⁄ 字号 评论关闭

传送门:【HDU】1531 King

题目分析:差分约束!题目意思看了半天。。。。题目不难,但是陷阱很好。。。。

首先对于每个式子si ni gt ki,令v=si+ni,u=si-1,则有xv-xu>ki --> xv-xu>=ki+1 -->xu-xv<=-ki-1,可以建边(v,u,-ki-1),对于每个式子si ni lt ki,令v=si+ni,u=si-1,则有xv-xu<ki --> xv-xu<=ki-1,可以建边(u,v,ki-1),然后设立一个源点xs,对所有的xi建边(xs,xi,0),跑一遍带负环判断的spfa,如果一个xi被更新了至少n+1次,那么说明题目中存在负环。否则没有负环。

坑爹的就是这至少n+1次。。我设成n次就错了。。。其实也对,加上s一共n+1个点。。。

代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;

#define REP( i , a , b ) for ( int i = a ; i < b ; ++ i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REV( i , a , b ) for ( int i = a ; i >= b ; -- i )
#define CLR( a , x ) memset ( a , x , sizeof a )

const int MAXN = 105 ;
const int MAXQ = 105 ;
const int MAXE = 1000 ;
const int INF = 0x3f3f3f3f ;

struct Edge {
	int v , c ;
	Edge *next ;
	Edge () {}
	Edge ( int v , int c , Edge *next ) : v ( v ) , c ( c ) , next ( next ) {}
} E[MAXE] , *H[MAXN] , *cntE ;

int d[MAXN] ;
int in[MAXN] ;
bool inq[MAXN] ;
int Q[MAXN] , head , tail ;
int n , m ;
int s ;

void init () {
	cntE = E ;
	CLR ( H , 0 ) ;
}

void addedge ( int u , int v , int c ) {
	cntE -> v = v ;
	cntE -> c = c ;
	cntE -> next = H[u] ;
	H[u] = cntE ++ ;
}

bool spfa () {
	CLR ( in , 0 ) ;
	CLR ( inq , 0 ) ;
	CLR ( d , INF ) ;
	head = tail = 0 ;
	d[s] = 0 ;
	Q[tail ++] = s ;
	while ( head != tail ) {
		int u = Q[head ++] ;
		if ( head == MAXQ ) head = 0 ;
		inq[u] = 0 ;
		for ( Edge* e = H[u] ; e ; e = e -> next ) {
			int v = e -> v ;
			if ( d[v] > d[u] + e -> c ) {
				d[v] = d[u] + e -> c ;
				if ( !inq[v] ) {
					inq[v] = 1 ;
					if ( n + 1 == ++ in[v] )
						return false ;
					if ( d[v] < d[Q[head]] ) {
						if ( !head ) head = MAXQ ;
						Q[-- head] = v ;
					} else {
						Q[tail ++] = v ;
						if ( tail == MAXQ ) tail = 0 ;
					}
				}
			}
		}
	}
	return true ;
}

void solve () {
	int u , v , d ;
	char str[5] ;
	init () ;
	REP ( i , 0 , m ) {
		scanf ( "%d%d%s%d" , &u , &v , str , &d ) ;
		v += u ;
		-- u ;
		if ( !strcmp ( str , "gt" ) ) addedge ( v , u , - d - 1 ) ;
		else addedge ( u , v , d - 1 ) ;
	}
	s = n + 1 ;
	FOR ( i , 1 , n ) addedge ( s , i , 0 ) ;
	bool flag = spfa () ;
	printf ( "%s\n" , flag ? "lamentable kingdom" : "successful conspiracy" ) ;
}
	

int main () {
	while ( ~scanf ( "%d%d" , &n , &m ) && n )
		solve () ;
	return 0 ;
}

抱歉!评论已关闭.