网络流24题 洛谷 3355 骑士共存

Posted horsepower2001

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络流24题 洛谷 3355 骑士共存相关的知识,希望对你有一定的参考价值。

转换成最小割;

技术分享图片
#include <bits/stdc++.h>

using  namespace  std ;

const  int  mx [ 9 ] = { 2 , 2 , -2 , -2 , -1 , 1 , -1 , 1 } ;
const  int  my [ 9 ] = { -1 , 1 , -1 , 1 , 2 , 2 , -2 , -2 } ; 

const  int  N = 100000 + 10 , inf = 1e8 + 7 ;

queue < int >  q ;

int  hh [ N << 2 ] , head [ N << 2 ] , nxt [ N << 2 ] , to [ N << 2 ] , cn = 1 ;
int  flt [ N << 2 ] , dis [ N ] ;
int  src , sink , x , y , n , m ;
bool  vis [ N ] , tag [ 500 ] [ 500 ] ;

int  minx ( int  a , int  b ) {
    return  a > b ? b : a ;
}

void  create ( int  u , int  v , int  f ) {
    cn ++ ;
    to [ cn ] = v ;
    flt [ cn ] = f ; 
    nxt [ cn ] = head [ u ] ;
    head [ u ] = cn ;
    cn ++ ;
    to [ cn ] = u ;
    flt [ cn ] = 0 ; 
    nxt [ cn ] = head [ v ] ;
    head [ v ] = cn ;
}

bool  bfs ( ) {
    memset ( vis , 0 , sizeof ( vis ) ) ;
    memset ( dis , 0 , sizeof ( dis ) ) ;
    q . push ( src ) ;
    vis [ src ] = 1 ;
    while ( ! q . empty ( ) ) {
        int  tmp = q . front ( ) ;
        q . pop ( ) ;
        for ( int  i = head [ tmp ] ; i ; i = nxt [ i ] ) {
            int  v = to [ i ] ;
            if ( flt [ i ]  &&  ! vis [ v ] ) {
                dis [ v ] = dis [ tmp ] + 1 ;
                q . push ( v ) ;
                vis [ v ] = true ;
            }
        }
    } 
    return  vis [ sink ] ;
}
int  dinic ( int  u , int  delta ) {
    if ( u == sink )  return  delta ;
    int  res = 0 , v ;
    for ( int  i = hh [ u ] ; i  &&  delta ; i = nxt [ i ] ) {
        v = to [ i ] ;
        if ( flt [ i ]  &&  dis [ v ] == dis [ u ] + 1 ) {
            int  dd = dinic ( v , minx ( delta , flt [ i ] ) ) ;
            flt [ i ] -= dd ;
            flt [ i ^ 1 ] += dd ;
            res += dd ;
            delta -= dd ;
            hh [ u ] = i ;
        }
    }
    return  res ;
}

int  main ( ) {
    
    scanf ( "%d%d" , & n , & m ) ;
    
    src = 0 ; sink = n * n + 1 ; 
    
    for ( int  i = 1 ; i <= m ; i ++ ) {
        scanf ( "%d%d" , & x , & y ) ;
        tag [ x ] [ y ] = 1 ;
    }
    
    for ( int  i = 1 ; i <= n ; i ++ )
        for ( int  j = 1 ; j <= n ; j ++ )
        {
            if( tag [ i ] [ j ] )  continue ;
            int  id = ( i - 1 ) * n + j ;
            if( ( i + j ) & 1 )
            {
                create ( src , id , 1 ) ;
                for( int  k = 0 ; k <= 7 ; k ++ )
                {
                    int  t1 = i + mx [ k ] , t2 = j + my [ k ] ;
                    if ( t1 <= 0  ||  t1 > n  ||  t2 <= 0  ||  t2 > n  ||  tag [ t1 ] [ t2 ] ) continue ;
                    create ( id , ( t1 - 1 ) * n + t2 , inf ) ;
                }
            } else create ( id , sink , 1 );
        }
    
    int  ans = 0 ;
    
    while ( bfs ( ) ) {
        ans += dinic ( src , inf ) ; 
        for ( int  i = 0 ; i <= n * n + 1 ; i ++ ) 
            hh [ i ] = head [ i ] ;
    }
    
    printf ( "%d" , n * n - m - ans ) ;
    
    return  0 ;
}
Ans

 

以上是关于网络流24题 洛谷 3355 骑士共存的主要内容,如果未能解决你的问题,请参考以下文章

网络流24题骑士共存问题

P3355 骑士共存问题 网络流

[网络流24题] 骑士共存

[网络流24题] 骑士共存问题

网络流24题骑士共存问题(最大流)

AC日记——[网络流24题]骑士共存 cogs 746