题目大意:给出一张地图,一个军队要征战整个土地。一块土地只能经过一次,有X的地方不能走,军队只会走R*C个格子,只会向下走,问最少需要多少军队能够征战所有的土地
题解:比较naive的DAG最小路径覆盖,把可行点连边,搞成二分图就好了
我的收获:水啊
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define M 2607
int m,n,r,c,cnt;
int lik[M],id[55][55];
bool mp[M][M],vis[M];
char s[55][55];
bool hungary(int x)
{
for(int i=1;i<=cnt;i++){
if(!mp[x][i]||vis[i]) continue;
vis[i]=true;
if(!lik[i]||hungary(lik[i])) return lik[i]=x;
}
return false;
}
void work()
{
int ans=0;
for(int i=1;i<=cnt;i++){
memset(vis,0,sizeof(vis));
if(hungary(i)) ans++;
}
cout<<cnt-ans<<endl;
}
void build()
{
int dx[]={r,r,c,c},dy[]={c,-c,r,-r};
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(s[i][j]=='.')
for(int k=0;k<4;k++)
{
int fx=i+dx[k],fy=j+dy[k];
if(s[fx][fy]=='X'||fx<1||fx>n||fy<1||fy>m) continue;
mp[id[i][j]][id[fx][fy]]=1;
}
}
void init()
{
cin>>n>>m>>r>>c;
for(int i=1;i<=n;i++){
scanf("%s",s[i]+1);
for(int j=1;j<=m;j++) if(s[i][j]=='.') id[i][j]=++cnt;//只把可行点建图
}
build();
}
int main()
{
init();
work();
return 0;
}