水水水。。
裸最小路径覆盖。。
我为何这么水。
#include <cstdio>
#include <cstring>
using namespace std;
int dx[5],dy[5];
int n,m,r,c,sz;
bool a[55][55];
struct edge {
int v,next;
}e[10010];
int cnt,head[5010];
int Linkx[5010],Linky[5010];
bool vis[5010];
int read_int () {
char c = getchar();
int re = 0;
for(;c > '9' || c < '0';c = getchar());
for(;c >= '0' && c <= '9';c = getchar())
re = re * 10 + c - '0';
return re;
}
void adde (int u,int v) {
e[cnt].v = v;
e[cnt].next = head[u];
head[u] = cnt++;
}
int cal (int x,int y) {
return (x - 1) * m + y;
}
int dfs (int u) {
for(int i = head[u];i != -1;i = e[i].next) {
int v = e[i].v;
if(vis[v])
continue;
vis[v] = 1;
if(!Linky[v] || dfs(Linky[v])) {
Linkx[u] = v;
Linky[v] = u;
return 1;
}
}
return 0;
}
int main () {
memset(head,-1,sizeof head);
n = read_int();
m = read_int();
r = read_int();
c = read_int();
sz = n * m;
dx[1] = -r;
dy[1] = -c;
dx[2] = -c;
dy[2] = -r;
dx[3] = -r;
dy[3] = c;
dx[4] = -c;
dy[4] = r;
for(int i = 1;i <= n;++i) {
for(int j = 1;j <= m;++j) {
if(getchar() == '.') {
a[i][j] = 1;
for(int k = 1;k <= 4;++k) {
int x = i + dx[k];
int y = j + dy[k];
if(x >= 1 && x <= n && y >= 1 && y <= m && a[x][y])
adde(cal(x,y),cal(i,j) + n * m);
}
}
else sz--;
}
getchar();
}
int ans = 0;
for(int i = 1;i <= n * m;++i) {
if(!Linkx[i]) {
memset(vis,0,sizeof vis);
ans += dfs(i);
}
}
printf("%d\n",sz - ans);
}