Knight coloca ch6091 (bipartito gráfico máximo conjunto independiente)

Tema Enlace  https://www.acwing.com/problem/content/380/

ideas:

Dejar que los demás buscando el máximo número de caballeros no puede atacar de venta. Se puede considerar, el punto de dibujo puede estar vinculado a cada uno otro borde de ataque, será un gráfico, y es un gráfico bipartito. Si usted no puede decir lo que queda parte del nodo que es la parte derecha del nodo, puede utilizar la tinción de ellos por separado. Ahora se requiere ninguna conexión entre un conjunto máximo para satisfacer cualquier conjunto de puntos, es decir, el conjunto máximo independiente. = Máximo total punto gráfico bipartito conjunto independiente - coincidencia máxima. En este problema, el número total de puntos de la gráfica bipartita puede ser representado por los puntos método de teñido teñidas, la representación más simple es, un total de N * M puntos, que a su vez t están prohibidos colocan puntos, entonces esto t puntos que ya no aparecen en el gráfico bipartito, por lo que el número total de puntos es el n-MT * , entonces el diagrama de construcción más grande en busca de igualar.

/**
 * Author: correct
 */
#include <bits/stdc++.h>
using namespace std;
#define mem(a, b) memset(a, b, sizeof a)
const int N = 1e5;
int head[N], nex[N], to[N], cnt;
int n, m, t;
int color[110][110];
int dx[] = {2, 2, -2, -2, 1, 1, -1, -1};
int dy[] = {1, -1, 1, -1, 2, -2, 2, -2};
int match[N];
bool w[110][110];
bool vis[N];
void pre_work(){
	mem(head, -1);
	mem(nex, -1);
	cnt = 0;
	mem(color, 0);
	mem(match, -1);
	mem(w, true);
}
void add(int a, int b){
	++cnt;
	to[cnt] = b;
	nex[cnt] = head[a];
	head[a] = cnt;
}
int get(int x, int y){
	return (x - 1) * 1000 + y;
}
bool check(int xx, int yy){
	if (xx >= 1 && xx <= n && yy >= 1 && yy <= m && w[xx][yy])return 1;
	return 0;
}
void build(){
	for (int i = 1; i <= n; i++){
		for (int j = 1; j <= m; j++){
			for (int k = 0; k <= 7; k++){
				int xx = i + dx[k];
				int yy = j + dy[k];
				if (check(xx, yy)){
					add(get(i, j), get(xx, yy));
				}
			}
		}
	}
}
int getX(int x){
	return x / 1000 + 1;
}
int getY(int x){
	return x % 1000;
}
bool colors(int x, int c){
	int xx, yy;
	yy = x % 1000;
	xx = x / 1000 + 1;
	color[xx][yy] = c;
	for (int i = head[x]; ~i; i = nex[i]){
		int y = to[i];
		if (!color[getX(y)][getY(y)]){
			colors(y, 3 - c);
		}
		else if(color[getX(y)][getY(y)] == c){
			return 0;
		}
	}
	return 1;
}
bool dfs(int x){
	for (int i = head[x]; ~i; i = nex[i]){
		int y = to[i];
		if (vis[y])continue;
		vis[y] = 1;
		if (match[y] == -1 || dfs(match[y])){
			match[y] = x;
			return 1;
		}
	}
	return 0;
}
int solve(){
	build();
	int ans = n * m - t;
	for (int i = 1; i <= n; i++){
		for (int j = 1; j <= m; j++){
			if (!color[i][j])colors(get(i, j), 1);
		}
	}
	for (int i = 1; i <= n; i++){
		for (int j = 1; j <= m; j++){
			if (color[i][j] == 1 && w[i][j]){
				mem(vis, 0);
				if (dfs(get(i, j)))ans--;
			}
		}
	}
	return ans;
}
int main()
{
	pre_work();
	scanf("%d %d %d", &n, &m, &t);
	for (int i = 0; i < t; i++){
		int x, y;
		scanf("%d %d", &x, &y);
		w[x][y] = 0;
	}
	printf("%d\n", solve());
	return 0;
}

 

Publicados 204 artículos originales · elogios ganado 13 · Vistas a 10000 +

Supongo que te gusta

Origin blog.csdn.net/weixin_43701790/article/details/104662347
Recomendado
Clasificación