您的位置:首页 > 其它

[POJ 2226] Muddy Fields

2018-03-09 20:17 211 查看

题目

Description

如何放木板保证只覆盖到 ’*’ 而没有覆盖到 ’.’

Solution

(我太废了竟然想这题想了一个小时)考虑当前需要被覆盖的点 (x,y),假设有一块横着铺的木板 i ,一块竖着铺的木板 j,这两块木板同时经过了 (x,y),那么我们以横着铺的木板为左部点,竖着铺的木板为右部点,将这两个木板之间连一条边。问题就转化为了求二分图上的最小点覆盖。(因为每个要覆盖的点是一条边,要让每个点都被覆盖,等价于最小点覆盖)。

Code

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;

int pre[2505];
int head[2505];
bool vis[2505];
int mp[55][55];
int m,n,cnt,tot1,tot2,ans;
int xx[55][55],yy[55][55];

struct Edge{
int to,nxt;
}edge[250005];

void add(int x,int y){
edge[++cnt].to=y;
edge[cnt].nxt=head[x];
head[x]=cnt;
}

bool dfs(int now){
if(vis[now]) return 0;
vis[now]=1;
for(int i=head[now];i;i=edge[i].nxt){
int to=edge[i].to;
if(!pre[to]||dfs(pre[to])){
pre[to]=now;
return 1;
}
}
return 0;
}

signed main(){
scanf("%d%d",&m,&n);
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
char ch;cin>>ch;
if(ch=='*') mp[i][j]=1;
else mp[i][j]=0;
}
}
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(!mp[i][j]) continue;
if(mp[i-1][j]) xx[i][j]=xx[i-1][j];
else xx[i][j]=++tot1;
if(mp[i][j-1]) yy[i][j]=yy[i][j-1];
else yy[i][j]=++tot2;
}
}
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(!mp[i][j]) continue;
add(xx[i][j],yy[i][j]);
}
}
for(int i=1;i<=tot1;i++){
memset(vis,0,sizeof vis);
if(dfs(i)) ans++;
}
printf("%d",ans);
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: