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;

}

 




你可能感兴趣的:(Field)