转换成最小割;
#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 ; }