题面
题解
貌似是一道最小路径覆盖的板子题……
不会的就学学吧,网络流经典建模之一。
不过因为是二分图,所以也可以用匈牙利。
这里的代码是匈牙利的写法,很短。
#include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 7000
#define ac 800000
#define id(i, j) ((i - 1) * m + j)
int n, m, l, r, ans;
int link[AC];
int Head[AC], date[ac], Next[ac], tot;
char s[60][60];
bool vis[AC];
inline void add(int f, int w)
{
date[++ tot] = w, Next[tot] = Head[f], Head[f] = tot;
//date[++ tot] = f, Next[tot] = Head[w], Head[w] = tot;
//printf("%d ---> %d
", f, w);
}
void pre()
{
scanf("%d%d%d%d", &n, &m, &l, &r);
for(R i = 1; i <= n; i ++) scanf("%s", s[i] + 1);
int a[10] = {l, l, r, r}, b[5] = {r, -r, l, -l};
for(R i = 1; i <= n; i ++)
for(R j = 1; j <= m; j ++)
{
if(s[i][j] == 'x') continue;
++ ans;
for(R k = 0; k < 4; k ++)
{
int x = i + a[k], y = j + b[k];
if(x <= 0 || x > n || y <= 0 || y > m || s[x][y] == 'x') continue;
add(id(i, j), id(x, y));
}
}
}
bool dfs(int x)
{
for(R i = Head[x]; i; i = Next[i])
{
int now = date[i];
if(vis[now]) continue;
vis[now] = true;
if(!link[now] || dfs(link[now])) {link[now] = x; return true;}
}
return false;
}
void work()
{
for(R i = 1; i <= n * m; i ++)
{
memset(vis, 0, sizeof(vis));
if(dfs(i)) -- ans;
}
printf("%d
", ans);
}
int main()
{
// freopen("in.in", "r", stdin);
pre();
work();
// fclose(stdin);
return 0;
}