最小点覆盖
#include <iostream>
#include <string.h>
using namespace std;
const int size = 700;
char mapp[60][60];
int num1, num2;
int mapp1[size][size], mapp2[size][size];
bool maze[size][size];
const int Go[2][2] = {{0, 1}, {1, 0}};
int n, m;
bool check(int x, int y)
{
return (x >= 0 && x < n && y >= 0 && y < m);
}
int xx, yy, st;
void dfs(int sx, int sy, int x[][size], int num)
{
if (x[sx][sy] != -1)return ;
x[sx][sy] = num;
xx = sx + Go[st][0], yy = sy + Go[st][1];
if (check(xx, yy)){
dfs(xx, yy, x, num);
}
}
int match[size];
bool visited[size];
bool dfs1(int x, int num)
{
for (int i = 1; i <= num; i ++){
if (!maze[x][i] || visited[i])continue;
visited[i] = true;
if (match[i] == -1 || dfs1(match[i], num)){
match[i] = x;
return true;
}
}
return false;
}
int main()
{
while (scanf("%d%d", &n, &m) != EOF){
memset(mapp1, 0, sizeof(mapp1));
memset(mapp2, 0, sizeof(mapp2));
for (int i = 0; i < n; i ++){
scanf("%s", mapp[i]);
for (int j = 0; j < m; j ++){
if (mapp[i][j] == '*'){
mapp1[i][j] = mapp2[i][j] = -1;
}
}
}
st = 0, num1 = 1;
for (int i = 0; i < n; i ++){
for (int j = 0; j < m; j ++){
if (mapp1[i][j] == -1){
dfs(i, j, mapp1, num1);
num1 ++;
}
}
}
st = 1, num2 = 1;
for (int i = 0; i < m; i ++){
for (int j = 0; j < n; j ++){
if (mapp2[j][i] == -1){
dfs(j, i, mapp2, num2);
num2 ++;
}
}
}
memset(maze, false, sizeof(maze));
for (int i = 0; i < n; i ++){
for (int j = 0; j < m; j ++){
if (mapp[i][j] == '*'){
maze[mapp1[i][j]][mapp2[i][j]] = true;
}
}
}
int ans = 0;
memset(match, -1, sizeof(match));
for (int i = 1; i <= num1; i ++){
memset(visited, false, sizeof(visited));
if (dfs1(i, num2))ans ++;
}
printf("%d\n", ans);
}
return 0;
}