POJ2226 Muddy Fields

来源:互联网 发布:火炮兰灵族捏脸数据 编辑:程序博客网 时间:2024/03/29 18:28

这道题目算是二分图中比较难的一道,明明知道是二分图问题,应该用匈牙利算法解决,可是看了半天也没发现二分图的特点在哪里,后来看了高人的博客才明白要把二维图抽象出来,将每一道x方向相连的“*”看做一个点,所有x方向的“点”构成一个集合,同理所有Y方向的“点”构成另外一个集合,若横向的一行和纵向的一列有交点则将两个“点”连起来,这样就是一个二分图了。真心佩服第一个想到要这样做的大神。
题目链接:http://poj.org/problem?id=2226
题目大意:有一个R*C大小的牧场,下雨过后一些点变得很泥泞,为了防止把牛的蹄子弄脏,牧场主决定要在泥泞的点上覆盖木板,木板宽一个单位,但是可以任意长度,求最少需要多少块木板。
解题思路:见如上分析,将图抽象成二部图,再利用匈牙利算法。

//AC代码:#include <iostream>#include <string.h>using namespace std;#define MAX 1000bool 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;}
0 0
原创粉丝点击