'''
每个骑士和它能跳到的位置这两个方格颜色肯定是不一样的,所以可以转换成二分图问题
等价于问怎么样选最多的点,让任意两个点都没有边相连,就是求最大独立集的大小,也就是
总节点数减去二分图最大匹配数,注意不能放骑士的点也要减掉
'''
import sys
from collections import deque
class Bipartite:
# 传入图中的边信息,所有边起点属于二分图part1, 所有边终点属于二分图part2, 输入数据自行保证没有重边
# 节点编号从1开始,所有节点编号为1, 2, 3, ..... max_node_num
def __init__(self, edges, max_node_num):
self.edges = edges
self.max_ndoe_num = max_node_num
self.__match_result = None
# 获取二分图最大匹配数量, 如果无法进行二分图匹配,返回None, 正常情况返回 (最大匹配数,最大匹配边列表)
# 节点编号从1开始,所有节点编号为1, 2, 3, ..... max_node_num
def getMaxMatchNum(self):
max_node_num = self.max_ndoe_num
# 构建邻接表
link = [[] for _ in range(max_node_num + 1)]
for a, b in self.edges:
link[a].append(b)
part1_nodes = set([a for a, _ in self.edges]) # 所有属于part1中的节点
part2_node2matched = [None] * (max_node_num + 1) # 记录part2中节点和part1中哪个节点匹配
cnt = 0
for start_node in part1_nodes:
que = deque()
pre = [None] * (max_node_num + 1)
visited = [0] * (max_node_num + 1)
visited[start_node] = 1
que.append(start_node)
end_node = None
find_expand_path = False
while len(que) > 0:
cur = que.popleft()
for next in link[cur]:
if visited[next] == 0:
visited[next] = 1
pre[next] = cur
if part2_node2matched[next] is None:
# 找到非匹配点,也就是找到了增广路径
end_node = next
find_expand_path = True
break
else:
pre[part2_node2matched[next]] = next
que.append(part2_node2matched[next])
if find_expand_path:
flag = True
if end_node:
while pre[end_node] is not None:
if flag:
part2_node2matched[end_node] = pre[end_node]
end_node = pre[end_node]
flag = not flag
cnt += 1
# 读取匹配的边
match_edges = []
for node in range(1, max_node_num + 1):
if part2_node2matched[node] is not None:
match_edges.append((part2_node2matched[node], node))
self.__match_result = cnt, match_edges
return self.__match_result[0]
s = sys.stdin.readline()
m, n, p = map(int, s.split())
grid = [[0] * (n+1) for _ in range(m+1)]
for i in range(p):
s = sys.stdin.readline()
a, b = map(int, s.split())
grid[a][b] = 1
edges = []
for i in range(1, m+1):
for j in range(1, n+1):
if grid[i][j] == 1:
continue
c = None
idx = (i - 1) * n + j
if n % 2 == 0:
c = idx & 1 if i % 2 == 0 else 1 - (idx & 1)
else:
c = 0 if idx & 1 else 1
for ii, jj in [(i-1, j+2), (i-2, j+1), (i+1, j+2), (i+2, j+1)]:
if ii >= 1 and ii <= m and jj >= 1 and jj <= n and grid[ii][jj] == 0:
#print(i, j, ii, jj)
if c == 0:
edges.append(((i-1)*n+j, (ii-1)*n+jj))
else:
edges.append(((ii-1)*n+jj, (i-1)*n+j))
print(m*n - p - Bipartite(edges, max_node_num=m*n).getMaxMatchNum())