zoukankan      html  css  js  c++  java
  • [CQOI2014]危桥

    题目

    点这里看题目。

    分析

    首先可以发现 " 往返 " 可以单纯考虑成 " 路径走两遍 " ,也不会影响正确性。那么一条危桥就只能走一次了

    初看显然会以为是一个多源汇网络流问题。

    此时就出现了两个问题:

    1. 有可能 (a_1 ightarrow b_2) 流了一些, (b_1 ightarrow a_2) 也可以流一些,那么就可能存在 " 虚假 " 的可行方案。
    2. 一条危桥可能正方向流一次,反方向流一次,结果就啥也没有了。

    解决第一个问题的方法是,如果我们能让 (a_1) 也向 (b_1) 流一些,那么将 (a_1 ightarrow b_2) 的流反向之后我们就得到了一些可行流。

    根据这个思路,我们可以尝试交换 (b_1)(b_2) ,再跑最大流。如果两次都满流,那么就说明绝对有解。

    下面将说明正确性:

    咕咕咕了

    小结:

    通过更换源汇、反向造流的思路值得借鉴。

    代码

    #include <cstdio>
    
    const int INF = 0x3f3f3f3f;
    const int MAXN = 1e4 + 5, MAXM = 1e5 + 5;
    
    template<typename _T>
    void read( _T &x )
    {
    	x = 0; char s = getchar(); int f = 1;
    	while( s < '0' || '9' < s ) { f = 1; if( s == '-' ) f = -1; s = getchar(); }
    	while( '0' <= s && s <= '9' ) { x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar(); }
    	x *= f;
    }
    
    template<typename _T>
    void write( _T x )
    {
    	if( x < 0 ) putchar( '-' ), x = -x;
    	if( 9 < x ) write( x / 10 );
    	putchar( x % 10 + '0' );
    }
    
    template<typename _T>
    _T MIN( const _T a, const _T b )
    {
    	return a < b ? a : b;
    }
    
    template<typename _T>
    void swapp( _T &x, _T &y )
    {
    	_T t = x; x = y, y = t;
    }
    
    struct Edge
    {
    	int to, nxt, c;
    }Graph[MAXM << 1];
    
    char S[55][55];
    
    int q[MAXN];
    int head[MAXN], dep[MAXN], cur[MAXN];
    int N, A1, A2, AN, B1, B2, BN, cnt = 1, tot;
    
    void AddEdge( const int from, const int to, const int C ) 
    {
    	Graph[++ cnt].to = to, Graph[cnt].nxt = head[from];
    	Graph[cnt].c = C, head[from] = cnt;
    }
    
    void AddE( const int from, const int to, const int C ) { AddEdge( from, to, C ), AddEdge( to, from, 0 ); }
    
    bool BFS( const int S, const int T )
    {
    	int h = 1, t = 0, u, v;
    	for( int i = 1 ; i <= tot ; i ++ ) dep[i] = INF;
    	dep[q[++ t] = S] = 0;
    	while( h <= t )
    	{
    		u = q[h ++];
    		for( int i = head[u] ; i ; i = Graph[i].nxt )
    			if( Graph[i].c && dep[v = Graph[i].to] > dep[u] + 1 )
    				dep[q[++ t] = v] = dep[u] + 1;
    	}
    	return dep[T] < INF;
    }
    
    int DFS( const int u, const int lin, const int T )
    {
    	if( u == T ) return lin;
    	int used = 0, ret, v, c;
    	for( int &i = cur[u] ; i ; i = Graph[i].nxt )
    	{
    		v = Graph[i].to, c = Graph[i].c;
    		if( dep[v] == dep[u] + 1 && c && ( ret = DFS( v, MIN( lin - used, c ), T ) ) )
    		{
    			used += ret, Graph[i].c -= ret, Graph[i ^ 1].c += ret;
    			if( used == lin ) break;
    		}
    	}
    	if( used < lin ) dep[u] = INF;
    	return used;
    }
    
    int Dinic( const int S, const int T )
    {
    	int ret = 0;
    	while( BFS( S, T ) )
    	{
    		for( int i = 1 ; i <= tot ; i ++ ) cur[i] = head[i];
    		ret += DFS( S, INF, T );
    	}
    	return ret;
    }
    
    void Clean()
    {
    	cnt = 1, tot = N;
    	for( int i = 1 ; i <= tot + 2 ; i ++ )
    		head[i] = q[i] = dep[i] = cur[i] = 0;
    }
    
    bool Chk()
    {
    	Clean();
    	const int s = ++ tot, t = ++ tot;
    	for( int i = 1 ; i <= N ; i ++ )
    		for( int j = 1 ; j <= N ; j ++ )
    		{
    			if( S[i][j] == 'O' ) AddE( i, j, 1 );
    			else if( S[i][j] == 'N' ) AddE( i, j, INF );
    		}
    	AddE( s, A1, AN ), AddE( s, B1, BN );
    	AddE( A2, t, AN ), AddE( B2, t, BN );
    	int flow = Dinic( s, t );
    	return flow == AN + BN;
    }
    
    int main()
    {
    	while( ~ scanf( "%d %d %d %d %d %d %d", &N, &A1, &A2, &AN, &B1, &B2, &BN ) )
    	{
    		A1 ++, A2 ++, B1 ++, B2 ++;
    		for( int i = 1 ; i <= N ; i ++ ) scanf( "%s", S[i] + 1 );
    		if( Chk() && ( swapp( B1, B2 ), Chk() ) ) puts( "Yes" );
    		else puts( "No" );
    	}
    	return 0;
    }
    
  • 相关阅读:
    叨叨叨
    四舍五入VS银行家舍入
    是雏还是鹰&mdash;&mdash;编程规范之变量命名
    .Net下二进制形式的文件(图片)的存储与读取(原创)
    asp.net中<%%>形式的用法(原创)
    让Hashtable支持自定义排序(原创)
    .NET下的迭代器(Iterator)模式
    本地视频播放-ios
    cocos2dx srand(time(NULL))重新设置一个随机种子
    cocos2dx 游戏重置方法
  • 原文地址:https://www.cnblogs.com/crashed/p/14175788.html
Copyright © 2011-2022 走看看