您的位置:首页 > 其它

poj 2226 Muddy Fields 最小顶点覆盖

2012-05-07 20:54 405 查看
题目链接:http://poj.org/problem?id=2226

这道题跟上一道很相似不同之处在于这里不是整行或者整列的删,而是连续的几个可以一起删,不连的不能删,这就要对原图进行处理,对原有的图行由上到下,列由左到右进行编号,作为x集合,在同一行且连续的编号一样,然后对原有的图列由左到右,行由上到下重新编号,作为y集合。之后就是二分图求最大匹配。

View Code

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int MAX=55;
int visit[20*MAX];
int map[MAX][MAX];
int res[20*MAX][20*MAX];
int use[20*MAX];
int n,m,xx,yy;
int solve(int x)
{
int i;
for(i=1;i<=yy;i++)
if(res[x][i]&&!visit[i])
{
visit[i]=1;
if(use[i]==-1||solve(use[i]))
{
use[i]=x;
return 1;
}
}
return 0;
}
int match()
{
int i,count=0;
for(i=1;i<=xx;i++)
{
memset(visit,0,sizeof(visit));
if(solve(i))count++;
}
return count;
}
void build()
{
int i,j,k;
k=0;
for(i=1;i<=n;i++)
for(j=1;j<=m;)
if(map[i][j]){
k++;
while(j<=m&&map[i][j])
map[i][j++]=k;
}
else j++;
xx=k;
k=0;
for(j=1;j<=m;j++)
for(i=1;i<=n;)
if(map[i][j]){
k++;
while(i<=n&&map[i][j])
{
res[map[i][j]][k]=1;
i++;
}
}
else i++;
yy=k;
}
int main()
{
int i,j;
char ch;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(map,0,sizeof(map));
memset(res,0,sizeof(res));
memset(use,-1,sizeof(use));
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
//scanf("%c",&ch);
cin>>ch;
if(ch=='*')
{
map[i][j]=1;
}
}
build();
printf("%d\n",match());
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: