匈牙利T了,Dinic飞了。。。
按奇偶连
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#define R(a,b,c) for(register int a = (b); (a) <= (c); ++(a))
#define nR(a,b,c) for(register int a = (b); (a) >= (c); --(a))
#define Fill(a,b) memset(a, b, sizeof(a))
#define Swap(a,b) ((a) ^= (b) ^= (a) ^= (b))
#define ll long long
#define u32 unsigned int
#define u64 unsigned long long
#define ON_DEBUGG
#ifdef ON_DEBUGG
#define D_e_Line printf("
----------
")
#define D_e(x) cout << (#x) << " : " << x << endl
#define Pause() system("pause")
#define FileOpen() freopen("in.txt", "r", stdin)
#define FileSave() freopen("out.txt", "w", stdout)
#include <ctime>
#define TIME() fprintf(stderr, "
time: %.3fms
", clock() * 1000.0 / CLOCKS_PER_SEC);
#else
#define D_e_Line ;
#define D_e(x) ;
#define Pause() ;
#define FileOpen() ;
#define FileSave() ;
#define TIME() ;
//char buf[1 << 21], *p1 = buf, *p2 = buf;
//#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
#endif
using namespace std;
struct ios{
template<typename ATP>inline ios& operator >> (ATP &x){
x = 0; int f = 1; char ch;
for(ch = getchar(); ch < '0' || ch > '9'; ch = getchar()) if(ch == '-') f = -1;
while(ch >= '0' && ch <= '9') x = x * 10 + (ch ^ '0'), ch = getchar();
x *= f;
return *this;
}
}io;
template<typename ATP>inline ATP Max(ATP a, ATP b){
return a > b ? a : b;
}
template<typename ATP>inline ATP Min(ATP a, ATP b){
return a < b ? a : b;
}
template<typename ATP>inline ATP Abs(ATP a){
return a < 0 ? -a : a;
}
const int N = 207;
const int M = 500007;
int n, m;
int S, T;
struct Edge{
int nxt, pre, w;
}e[M];
int head[M], cntEdge = 1;
inline void add(int u, int v, int w){
e[++cntEdge] = (Edge) { head[u], v, w}, head[u] = cntEdge;
}
inline void Add(int u, int v, int w){
add(u, v, w);
add(v, u, 0);
}
int cur[M];
int q[M], d[M];
inline bool BFS(){
int h = 0, t = 1;
R(i,S,T) d[i] = -1;
d[S] = 0, q[0] = S;
while(h != t){
int u = q[h++];
if(h > 500000) h = 0;
for(register int i = head[u]; i; i = e[i].nxt){
int v = e[i].pre;
if(e[i].w && d[v] == -1){
d[v] = d[u] + 1;
q[t++] = e[i].pre;
if(t > 500000) t = 0;
}
}
}
return d[T] != -1;
}
inline int DFS(int u, int f){
if(u == T) return f;
int w, used = 0;
for(register int i = cur[u]; i; i = e[i].nxt){
int v = e[i].pre;
if(d[v] == d[u] + 1){
w = DFS(v, Min(f - used, e[i].w));
e[i].w -= w, e[i ^ 1].w += w;
used += w;
if(used == f) return f;
}
}
if(!used) d[u] = -1;
return used;
}
inline int Dinic(){
int sum = 0;
while(BFS()){
R(i,S,T) cur[i] = head[i];
sum += DFS(S, 0x7fffffff);
}
return sum;
}
inline int ID(int x, int y){
return (x - 1) * m + y;
}
int mark[N][N];
int dx[] = {3, 3, 1, 1, -3, -3, -1, -1}, dy[] = {1, -1, 3, -3, 1, -1, 3, -3};
int main(){
int K;
io >> n >> m >> K;
S = 0, T = n * m + 1;
R(i,1,K){
int x, y;
io >> x >> y;
mark[x][y] = true;
}
R(i,1,n){
R(j,1,m){
int id = ID(i, j);
if(i & 1){
Add(S, id, 1);
}
else{
Add(id, T, 1);
}
}
}
R(i,1,n){
R(j,1,m){
if(mark[i][j]) continue;
int id = ID(i, j);
if(i & 1){
R(k,0,7){
int fx = i + dx[k], fy = j + dy[k];
if(fx < 1 || fx > n || fy < 1 || fy > m || mark[fx][fy]) continue;
int id2 = ID(fx, fy);
Add(id, id2, 1);
}
}
}
}
printf("%d", n * m - K - Dinic());
return 0;
}