您的位置:首页 > 其它

POJ2226 Muddy Fields

2015-11-07 22:10 190 查看
这道题目算是二分图中比较难的一道,明明知道是二分图问题,应该用匈牙利算法解决,可是看了半天也没发现二分图的特点在哪里,后来看了高人的博客才明白要把二维图抽象出来,将每一道x方向相连的“*”看做一个点,所有x方向的“点”构成一个集合,同理所有Y方向的“点”构成另外一个集合,若横向的一行和纵向的一列有交点则将两个“点”连起来,这样就是一个二分图了。真心佩服第一个想到要这样做的大神。

题目链接:http://poj.org/problem?id=2226

题目大意:有一个R*C大小的牧场,下雨过后一些点变得很泥泞,为了防止把牛的蹄子弄脏,牧场主决定要在泥泞的点上覆盖木板,木板宽一个单位,但是可以任意长度,求最少需要多少块木板。

解题思路:见如上分析,将图抽象成二部图,再利用匈牙利算法。

//AC代码:
#include <iostream>
#include <string.h>
using namespace std;
#define MAX 1000
bool used[MAX];
int linked[MAX];
int g[MAX][MAX];
int temp[MAX][MAX];
char graph[MAX][MAX];
int r,c;
int indexr,indexc;

void build()
{
memset(g,0,sizeof(g));
memset(temp,0,sizeof(temp));
int flag=0;
indexr=0;
indexc=0;
for(int i=1;i<=r;i++)
{
flag=0;
for(int j=1;j<=c;j++)
{
if(graph[i][j]=='*'&&flag==0){indexr++;flag=1;}
if(graph[i][j]=='*'&&flag==1)temp[i][j]=indexr;
if(graph[i][j]=='.')flag=0;
}
}
for(int j=1;j<=c;j++)
{
flag=0;
for(int i=1;i<=r;i++)
{
if(graph[i][j]=='*'&&flag==0){indexc++;flag=1;}
if(graph[i][j]=='*'&&flag==1)g[temp[i][j]][indexc]=1;
if(graph[i][j]=='.')flag=0;
}
}
}

bool dfs(int u)
{
int v;
for(v=1;v<=indexc;v++)
{
if(g[u][v]&&!used[v])
{
used[v] = true;
if(linked[v]==-1||dfs(linked[v]))
{
linked[v] = u;
return true;
}
}
}
return false;
}

int hungry()
{
int u;
int res=0;
memset(linked,-1,sizeof(linked));
for(u=1;u<=indexr;u++)
{
memset(used,0,sizeof(used));
if(dfs(u))res++;
}
return res;
}

int main()
{
while(cin>>r>>c)
{
for(int i=1;i<=r;i++)
{
for(int j=1;j<=c;j++)
{
cin>>graph[i][j];
}
}
build();
cout<<hungry()<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj 二分图 算法