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

【HDU】3035 War 对偶图最小割——最短路

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

传送门:【HDU】3035 War

题目分析:赤裸裸的对偶图全局最小割,最短路套上就好了。

debug了半天结果是define出了问题。。。唉。。果然是有副作用的。。

代码如下:

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

#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define REV( i , n ) for ( int i = n - 1 ; i >= 0 ; -- i )
#define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define FOV( i , a , b ) for ( int i = a ; i >= b ; -- i )
#define REPF( i , a , b ) for ( int i = a ; i < b ; ++ i )
#define REPV( i , a , b ) for ( int i = a - 1 ; i >= b ; -- i )

#define CLR( a , x ) memset ( a , x , sizeof a )
#define CPY( a , x ) memcpy ( a , x , sizeof a )

#define U( i , j ) ( ( ( ( i ) * m + ( j ) ) << 2 ) + 0 )
#define D( i , j ) ( ( ( ( i ) * m + ( j ) ) << 2 ) + 1 )
#define L( i , j ) ( ( ( ( i ) * m + ( j ) ) << 2 ) + 2 )
#define R( i , j ) ( ( ( ( i ) * m + ( j ) ) << 2 ) + 3 )

const int MAXN = 1000000 + 5 ;
const int MAXQ = 1000000 + 5 ;
const int MAXE = 3000000 + 5 ;
const int INF = 0x7f7f7f7f ;

struct Edge {
	int v , c , n ;
	Edge () {}
	Edge ( int v , int c , int n ) : v ( v ) , c ( c ) , n ( n ) {}
} ;

struct Graph {
	Edge E[MAXE] ;
	int H[MAXN] , cntE ;
	int d[MAXN] ;
	int Q[MAXQ] , head , tail ;
	bool inq[MAXN] ;
	int n , m ;
	int s , t ;
	
	void init () {
		cntE = 0 ;
		CLR ( H , -1 ) ;
	}
	
	void addedge ( int u , int v , int c ) {
		E[cntE] = Edge ( v , c , H[u] ) ;
		H[u] = cntE ++ ;
		E[cntE] = Edge ( u , c , H[v] ) ;
		H[v] = cntE ++ ;
	}
	
	void spfa () {
		CLR ( inq , false ) ;
		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] = false ;
			for ( int i = H[u] ; ~i ; i = E[i].n ) {
				int v = E[i].v ;
				if ( d[v] > d[u] + E[i].c ) {
					d[v] = d[u] + E[i].c ;
					if ( !inq[v] ) {
						inq[v] = true ;
						if ( d[v] < d[Q[head]] ) {
							if ( head == 0 )
								Q[head = MAXQ - 1] = v ;
							else
								Q[-- head] = v ;
						}
						else {
							Q[tail ++] = v ;
							if ( tail == MAXQ )
								tail = 0 ;
						}
					}
				}
			}
		}
	}
	
	void read ( int &x ) {
		x = 0 ;
		char c = ' ' ;
		while ( c < '0' || c > '9' )
			c = getchar () ;
		while ( c >= '0' && c <= '9' ) {
			x = x * 10 + c - '0' ;
			c = getchar () ;
		}
	}
	
	void input () {
		int x ;
		s = n * m * 4 ;
		t = s + 1 ;
		FOR ( i , 0 , n )
			REP ( j , m ) {
				read ( x ) ;
				if ( i == 0 )
					addedge ( U ( i , j ) , t               , x ) ;
				else if ( i < n )
					addedge ( U ( i , j ) , D ( i - 1 , j ) , x ) ;
				else
					addedge ( s           , D ( i - 1 , j ) , x ) ;
			}
		REP ( i , n )
			FOR ( j , 0 , m ) {
				read ( x ) ;
				if ( j == 0 )
					addedge ( s               , L ( i , j ) , x ) ;
				else if ( j < m )
					addedge ( R ( i , j - 1 ) , L ( i , j ) , x ) ;
				else
					addedge ( R ( i , j - 1 ) , t           , x ) ;
			}
		REP ( i , n << 1 )
			REP ( j , m << 1 ) {
				read ( x ) ;
				int ii = i >> 1 , jj = j >> 1 ;
				     if ( ( i & 1 ) == 0 && ( j & 1 ) == 0 )
					addedge ( L ( ii , jj ) , U ( ii , jj ) , x ) ;
				else if ( ( i & 1 ) == 0 && ( j & 1 ) == 1 )
					addedge ( U ( ii , jj ) , R ( ii , jj ) , x ) ;
				else if ( ( i & 1 ) == 1 && ( j & 1 ) == 0 )
					addedge ( L ( ii , jj ) , D ( ii , jj ) , x ) ;
				else if ( ( i & 1 ) == 1 && ( j & 1 ) == 1 )
					addedge ( D ( ii , jj ) , R ( ii , jj ) , x ) ;
			}
	}
	
	void solve () {
		init () ;
		input () ;
		spfa () ;
		printf ( "%d\n" , d[t] ) ;
	}
} x ;

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

抱歉!评论已关闭.