求助,90分
查看原帖
求助,90分
33978
eromangasensei楼主2020/10/23 12:41

大致思路就是把来回变成只去不回,然后把危桥设成 11 , 其他连边设成 INFINF ,从源点连出和终点连进的边设成 ananbnbn ,跑一遍最大流,再把 b1b1b2b2 交换,再跑一次最大流,若两次都是满流,就是存在一个合法方案,否则就没有方案。

DinicDinic 应该没有写错,貌似是建图的问题,就是找不出来。qwqqwq

WAWA 第二个点。

#include<bits/stdc++.h>
#define INF 1LL << 50
#define ll long long
#define For( X , From , To ) for( ll X = From; X <= To; X++ )
#define Rep( X , From , To ) for( ll X = From; X >= To; X-- )
using namespace std;
const ll MAXN = 4e3 + 5;
ll N , A1 , A2 , An , B1 , B2 , Bn , G[ MAXN ][ MAXN ];
ll Start , End , Ans1 , Ans2;
ll EdgeNum , Head[ MAXN ] , Next[ MAXN ] , Vet[ MAXN ] , Val[ MAXN ] , Cur[ MAXN ];
char Str[ MAXN ];
ll Depth[ MAXN ];
bool Visit[ MAXN ];
queue< ll > Q;
ll QP( ll B , ll K , ll Mod ){ ll Ans = 1; for( ; K; K >>= 1 , B = B * B % Mod ) if( K & 1 ) Ans = Ans * B % Mod; return Ans % Mod; }
template <class T> void Read( T &X ){
	X = 0; int F = 0; char Ch = getchar();
	while( Ch < '0' || Ch > '9' ){ F |= ( Ch == '-' ); Ch = getchar(); }
	while( Ch >= '0' && Ch <= '9' ){ X = X * 10 + ( Ch ^ 48 ); Ch = getchar(); }
	X = F ? -X : X;
}
inline void Write( ll X ){
	if( X < 0 ){
		putchar( '-' );
		X = -X;
	}
	if( X > 9 ) Write( X / 10 );
	putchar( ( X % 10 ) ^ 48 );
}
ll GCD( ll X , ll Y ){ return Y == 0 ? X : GCD( Y , X % Y ); }
void Add( ll U , ll V , ll Value ){
	Next[ EdgeNum ] = Head[ U ];
	Head[ U ] = EdgeNum;
	Vet[ EdgeNum ] = V;
	Val[ EdgeNum ] = Value;
	++ EdgeNum;
	Next[ EdgeNum ] = Head[ V ];
	Head[ V ] = EdgeNum;
	Vet[ EdgeNum ] = U;
	Val[ EdgeNum ] = 0;
	++ EdgeNum;
}
bool BFS(){
	For( i , 1 , N + 2 ) Depth[ i ] = INF;
	For( i , 1 , N + 2 ) Visit[ i ] = 0;
	Q.push( Start );
	Depth[ Start ] = 1;
	Visit[ Start ] = 1;
	while( ! Q.empty() ){
		ll U = Q.front();
		Q.pop();
		Visit[ U ] = 0;
		for( ll E = Head[ U ]; E != -1; E = Next[ E ] )
		if( Depth[ Vet[ E ] ] > Depth[ U ] + 1 && Val[ E ] ){
			if( ! Visit[ Vet[ E ] ] ){
				Q.push( Vet[ E ] );
				Visit[ Vet[ E ] ] = 1;
			}
			Depth[ Vet[ E ] ] = Depth[ U ] + 1;
		}
	}
	if( Depth[ End ] != INF ) return 1;
	return 0;
}
ll DFS( ll U , ll Flow ){
	if( U == End ) return Flow;
	ll NowFlow = 0;
	for( ll & E = Cur[ U ]; E != -1; E = Next[ E ] )
	if( Depth[ Vet[ E ] ] == Depth[ U ] + 1 && Val[ E ] && ( NowFlow = DFS( Vet[ E ] , min( Flow , Val[ E ] ) ) ) ){
		Val[ E ] -= NowFlow;
		Val[ E ^ 1 ] += NowFlow;
		return NowFlow;
	}
	return 0;
}
ll Dinic(){
	ll MAXFlow = 0 , AddFlow = 0;
	while( BFS() ){
		For( i , 1 , N + 2 ) Cur[ i ] = Head[ i ];
		while( AddFlow = DFS( Start , INF ) ) MAXFlow += AddFlow;
	}
	return MAXFlow;
}
int main(){
	//freopen( ".in" , "r" , stdin );
	//freopen( ".out" , "w" , stdout );
	while( ~ scanf( "%lld%lld%lld%lld%lld%lld%lld" , &N , &A1 , &A2 , &An , &B1 , &B2 , &Bn ) ){
		EdgeNum = 0;
		memset( Head , -1 , sizeof( Head ) );
		memset( Next , 0 , sizeof( Next ) );
		memset( Vet , 0 , sizeof( Vet ) );
		memset( Val , 0 , sizeof( Val ) );
		memset( G , 0 , sizeof( G ) );
		A1 ++; A2 ++;
		B1 ++; B2 ++;
		For( i , 1 , N ){
			scanf( "%s" , Str + 1 );
			For( j , 1 , N )
			if( Str[ j ] == 'O' ){
				G[ i ][ j ] = 1;
			}else
			if( Str[ j ] == 'N' ){
				G[ i ][ j ] = 2;
			}
		}
		For( i , 1 , N ){
			For( j , 1 , N )
			if( G[ i ][ j ] == 2 ){
				Add( i , j , INF );
			}else
			if( G[ i ][ j ] == 1 ){
				Add( i , j , 1 );
			}
		}
		Start = N + 1; End = N + 2;
		Add( N + 1 , A1 , An );
		Add( N + 1 , B1 , Bn );
		Add( A2 , N + 2 , An );
		Add( B2 , N + 2 , Bn );
		Ans1 = Dinic();
		EdgeNum = 0;
		memset( Head , -1 , sizeof( Head ) );
		memset( Next , 0 , sizeof( Next ) );
		memset( Vet , 0 , sizeof( Vet ) );
		memset( Val , 0 , sizeof( Val ) );
		For( i , 1 , N ){
			For( j , 1 , N )
			if( G[ i ][ j ] == 2 ){
				Add( i , j , INF );
			}else
			if( G[ i ][ j ] == 1 ){
				Add( i , j , 1 );
			}
		}
		Add( N + 1 , A1 , An );
		Add( N + 1 , B2 , Bn );
		Add( A2 , N + 2 , An );
		Add( B1 , N + 2 , Bn );
		Ans2 = Dinic();
		if( Ans1 == Ans2 && Ans1 == An + Bn ) printf( "Yes\n" );
		else printf( "No\n" );
	}
	return 0;
}
2020/10/23 12:41
加载中...