思路

很明显,一对相斥的位置,横纵坐标之和的奇偶性肯定不同.所以可以构成一个二分图.
源点向所有横纵坐标之和为奇数的点连边,为偶数的向汇点连边,边权都为1.
一对相斥的点之间连边,跑一遍最小割即可.
或者如果你懒得写网络流,你可以套用最大独立点集的模型,跑匈牙利即可.虽然效率比网络流低得多.

代码

#include<bits/stdc++.h>
using namespace std;
#define MAXN 60555
#define MAXM 520555

int N, M, TT;
int hd[MAXN], val[MAXM], nxt[MAXM], to[MAXM], tot(1);
int cur[MAXN];
int S, T, x, y;
bool mp[205][205];

void Add( int x, int y, int z ){
    nxt[++tot] = hd[x]; hd[x] = tot; to[tot] = y; val[tot] = z;
    nxt[++tot] = hd[y]; hd[y] = tot; to[tot] = x; val[tot] = 0;
}

int d[MAXN]; queue<int> Q;

bool BFS(){
    while( !Q.empty() ) Q.pop();
    memset( d, 0, sizeof d ); d[S] = 1; Q.push(S);
    while( !Q.empty() ){
        int t(Q.front()); Q.pop();
        for ( int i = hd[t]; i; i = nxt[i] ){
            if ( val[i] && !d[to[i]] ){
                d[to[i]] = d[t] + 1; Q.push(to[i]);
                if ( to[i] == T ) return 1;
            }
        }
    }
    return 0;
}

int DFS( int x, int fl ){
    if ( x == T ) return fl;
    int res(fl), k;
    for ( int &i = cur[x]; i && res; i = nxt[i] ){
        if ( val[i] && d[to[i]] == d[x] + 1 ){
            k = DFS( to[i], min( res, val[i] ) );
            if ( !k ) d[to[i]] = 0;
            res -= k; val[i] -= k; val[i ^ 1] += k;
        }
    }
    return fl - res;
}

int GetID( int x, int y ){ return ( x - 1 ) * M + y; }
int dir[][2] = { 1, 2, 2, 1, -1, -2, -2, -1, -1, 2, 2, -1, 1, -2, -2, 1 };

int main(){
    scanf( "%d%d%d", &N, &M, &TT );
    for ( int i = 1; i <= TT; ++i ) scanf( "%d%d", &x, &y ), mp[x][y] = 1;
    S = 0; T = N * M + 1;
    for ( int i = 1; i <= N; ++i )
        for ( int j = 1; j <= M; ++j ){
            if ( mp[i][j] ) continue;

            if ( ( i ^ j ) & 1 ) Add( S, GetID( i, j ), 1 );
            else{
                Add( GetID( i, j ), T, 1 );
                for ( int k = 0; k < 8; ++k ){
                    int tx(i + dir[k][0]), ty(j + dir[k][1]);
                    if ( tx > 0 && ty > 0 && tx <= N && ty <= M && !mp[tx][ty] ) Add( GetID( tx, ty ), GetID( i, j ), INT_MAX );
                }
            }
        }
    int ans( N * M - TT ), k;
    while( BFS() ){
        memcpy( cur, hd, sizeof hd );
        while( ( k = DFS( S, INT_MAX ) ) ) ans -= k;
    }
    printf( "%d\n", ans );
    return 0;
}