Acwing 372 chessboard coverage

Topic Link

Given a checkerboard N rows and N columns, the lattice is known that certain placement prohibited.

Up to put the number of request blocks to the length of the board 2, the width of the domino 1, domino ruled line coincides with the boundary (domino occupies two cells), and does not overlap any two dominoes.

Input Format

The first line contains two integers N and t, where t is the number of lattice disposed prohibited.

Then t lines contains two integers x and y, x represents a line located on the y-th column grid placement prohibited, the number of ranks from 1 starts.

Output Format

Output an integer representing the result.

data range

1≤N≤100

Sample output:

8 0

Sample output:

32

 Bipartite graph matching problem, as the domino edge points on the board as nodes in the graph, the board must be placed domino two adjacent points, and the coordinates and the two adjacent points (x + y) different parity, all the points can be divided into two parts by a parity and the coordinates, two points are considered as a bipartite graph of the set, and then run a bipartite graph Hungarian like. When built drawing attention because we ran from the maximum matching is a matching set of starting another collection, but this figure we need to run all the points, so there are two solutions.

1, through all points seeking maximum matching, the result is divided by 2

2, only the left portion or the right portion traversing bipartite graph (i.e., a parity of the same set of points)

I opened an array of small, bug change change for a long time QWQ

 

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 300;
int g[N][N];
int head[N * N], nex[N * N], to[N * N], cnt, match[N * N];
bool vis[N * N];
int dx[] = { 1, -1, 0, 0 };
int dy[] = { 0, 0, 1, -1 };
void init() {
	memset(g, 0, sizeof g);
	memset(head, -1, sizeof head);
	memset(nex, -1, sizeof nex);
	memset(vis, false, sizeof vis);
	memset(match, -1, sizeof match);
	cnt = 0;
}
void add(int a, int b) {
	cnt++;
	nex[cnt] = head[a];
	head[a] = cnt;
	to[cnt] = b;
}
bool dfs(int p) {
	for (int i = head[p]; i != -1; i = nex[i]) {
		int y = to[i];
		if (!vis[y]) {
			vis[y] = true;
			if (match[y] == -1 || dfs(match[y])) {
				match[y] = p;
				return true;
			}
		}
	}
	return false;
}
int main()
{
	int n, t;
	ios::sync_with_stdio(0);
	init();
	cin >> n >> t;
	while (t--) {
		int a, b;
		cin >> a >> b;
		g[a][b] = 1;
	}
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			if (g[i][j] == 0) {
				for (int k = 0; k < 4; k++) {
					int xx = i + dx[k];
					int yy = j + dy[k];
					if (xx >= 1 && xx <= n && yy >= 1 && yy <= n && g[xx][yy] == 0) {
						add((i - 1) * n + j, (xx - 1) * n + yy);
					}
				}
			}
		}
	}
	int res = 0;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			if ((i + j) % 2 == 1)continue;
			memset(vis, false, sizeof vis);
			if (dfs((i - 1) * n + j))res++;
		}
	}
	cout << res << "\n";
	return 0;
}

 

Published 143 original articles · won praise 11 · views 8194

Guess you like

Origin blog.csdn.net/weixin_43701790/article/details/103789231