_Never_

I walk slowly,but I will never stop.

导航

POJ 2226 Muddy Fields

本来想着是分别求各个连通图的最小点覆盖,总感觉是正确的却WA,看了别人的解题报告,有点不懈,更不明白自己的想法为什么错呢、、最终由试了一个例子,发现我真的错了!

*.*.|.
.***|*
***.|*
..*.|*

这个例子按照上边的思想答案仍是4,可惜不是4!发现漏洞了吧!所以说那样做是错的!
解题思路:
1.分别以行、列来用木板进行覆盖---依次编号
2.连接所有交叉的木板即连接覆盖同一污点的木板
3.求最大匹配==最小点覆盖数

我对该二分图的理解:
左右的点解对应着木板(行和列),而边对应着每一个污点,任一个污点都可以用行上或者列上的木板覆盖,所以求覆盖所有边的最少的点即为答案!

View Code
#include <stdio.h>
#include <memory.h>

#define N 1250
#define M 2500

typedef struct _Data
{
    int r,c;
}Data;

Data number[52][52];
char map[52][52];
int nodevp[N],nodeu[M],next[M],ind;
int R,C,num;

void addedge(int v,int u)
{
    nodeu[ind]=u;
    next[ind]=nodevp[v];
    nodevp[v]=ind++;
}


void buildGraph()
{
    int i,j,curNum;

//    for(i=0;i<52;i++)    number[0][i]=number[i][0]=1;
    
    curNum=1;
    for(i=1;i<=R;i++)
    {
        for(j=1;j<=C;j++)
            if(map[i][j]=='*')
            {
                if(map[i][j-1]=='*')
                    number[i][j].r=curNum;
                else
                    number[i][j].r=++curNum;
            }
        ++curNum;
    }    
    num=curNum;

    curNum=1;
    for(i=1;i<=C;i++)
    {
        for(j=1;j<=R;j++)
            if(map[j][i]=='*')
            {
                if(map[j-1][i]=='*')
                    number[j][i].c=curNum;
                else
                    number[j][i].c=++curNum;
            }
        ++curNum;
    }

    memset(nodevp,-1,sizeof(nodevp)); ind=0;
    for(i=1;i<=R;i++)
        for(j=1;j<=C;j++)
            if(number[i][j].r!=0)
                addedge(number[i][j].r,number[i][j].c);

}

int flag[N],pre[N];
int match(int v)
{
    int i,u;
    for(i=nodevp[v];~i;i=next[i])
    {
        u=nodeu[i];
        if(!flag[u])
        {
            if(pre[u]==-1 || (flag[u]=1,match(pre[u])) )
            {
                pre[u]=v;
                return 1;
            }
        }
    }
    return 0;
}

void solve()
{
    int i,ans=0;

    scanf("%d %d",&R,&C);
    
    for(i=0;i<52;i++)    map[0][i]=map[i][0]='*';
    for(i=1;i<=R;i++)    scanf("%s",map[i]+1);

    buildGraph();

    memset(pre,-1,sizeof(pre));
    for(i=1;i<=num;i++)    
    {
        memset(flag,0,sizeof(flag));
        ans+=match(i);
    }

    printf("%d\n",ans);
}


int main()
{
//    freopen("input.txt","r",stdin);
    
    solve();

    return 0;
}

 




posted on 2012-04-21 13:06  _Never_  阅读(294)  评论(0编辑  收藏  举报