POJ 2226 Muddy Fields (minimum coverage)

Topic Link  http://poj.org/problem?id=2226

Subject to the effect :

N * M in a grid-like surface, some of the lattice is muddy, the other lattice is clean.

Now necessitates the use of a width of 1, the length of any mud cover the wood while the cover can not clean the floor.

Each board must be covered with a plurality of complete lattice, wood may overlap.

How much wood requires a minimum demand.

Input Format

The first line contains two integers N and M.

Next N lines of M characters used to describe the ground, '*' represents a lattice mud, '' means no space between the grid and clean, character.

Output Format

Output an integer representing the result. Data range 1≤N, M≤50

Ideas :

 First talk minimum coverage is for the bipartite graph edges, so that the two end edges at least one point in the set S exists, the smallest point set S is the smallest coverage. You can change a more simple saying that for the two end sides, it can be placed in a point through which the concentrate or into another concentrated point, i.e. is optional. It is also an important symbol of the most under-covered, that is, the two meet at least one can be.

The title and cover a minimum of contact is not very intuitive. For a point, if it is muddy, definitely need to cover board, this board could put sideways, it may on end, but as long as you can put up to cover this point, for this point is to put a plate sideways or vertical both put a plate with at least choose one, which is the minimum coverage of this problem and contacted. If we continuously sideways and vertically continuous mud muddy block called row and column communication block communicates. Then clearly, both belonging to each point of a muddy block also belongs to a communication line communicating column block is mapped to the two end sides in FIG. It is possible to obtain the ranks of all the communication block, and FIG built, all the communication block row and column muddy points connected to one side of the communication block, to find the minimum coverage.

//============================================================================
// Name        : test.cpp
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#define mem(a, b) memset(a, b, sizeof a)
using namespace std;
const int N = 3e4;
int head[N], nex[N], to[N], cnt;
inline void add(int a, int b){
	++cnt;
	to[cnt] = b;
	nex[cnt] = head[a];
	head[a] = cnt;
}
int n, m;
char s[55][55];
int row[55][55], column[55][55];
int rows, columns;
int match[N];
bool vis[N];
void pre_work(){
	cnt = 0;
	mem(head, -1);
	mem(nex, -1);
	mem(match, -1);
	rows = 1;
	columns = 1;
	for (int i = 1; i <= n; i++){
		int j = 1;
		while (j <= m){
			while (j <= m && s[i][j] == '*'){
				row[i][j] = rows;
				j++;
			}
			++rows;
			while (j <= m && s[i][j] != '*'){
				j++;
			}
		}
	}
	for (int i = 1; i <= m; i++){
		int j = 1;
		while (j <= n){
			while (j <= n && s[j][i] == '*'){
				column[j][i] = columns;
				++j;
			}
			++columns;
			while (j <= n && s[j][i] != '*'){
				++j;
			}
		}
	}
	for (int i = 1; i <= n; i++){
		for (int j = 1; j <= m; j++){
			if (s[i][j] == '*'){
				add(row[i][j], column[i][j] + rows + 10);
				add(column[i][j] + rows + 10, row[i][j]);
			}
		}
	}
}
bool dfs(int x){
	for (int i = head[x]; i != -1; 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 main()
{
	scanf("%d %d", &n, &m);
	getchar();
	for (int i = 1; i <= n; i++){
		scanf("%s", s[i] + 1);
	}
	pre_work();
	int ans = 0;
	for (int i = 1; i < rows; i++){
		mem(vis, 0);
		if (dfs(i))++ans;
	}
	printf("%d\n", ans);
	return 0;
}

 

Published 204 original articles · won praise 13 · views 10000 +

Guess you like

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