POJ 2226 Muddy Fields

这道题是最小点覆盖的题,用最少的木板将泥地覆盖。我们建图时将横的线段看成二分图的X点,

将竖线段看成Y点。将每个横线段和竖线段编号,编号之后将有交点的横线段和竖线段连一条边,

求出最大匹配。 最小点覆盖 = 最大匹配。 

/*Accepted    2440 KB    16 ms    C++    2186 B    2012-07-28 16:18:28*/

#include<cstdio>

#include<cstring>

#include<cstdlib>

const int MAXN = 55;

int xM[MAXN * MAXN / 2], yM[MAXN * MAXN / 2];

bool g[MAXN * MAXN / 2][MAXN * MAXN / 2];

int R, C;

char map[MAXN][MAXN];

bool chk[MAXN * MAXN / 2];

int vN, uN;

int xr[MAXN][MAXN], yc[MAXN][MAXN];



bool SearchPath(int u)

{

    int v;

    for(v = 1; v <= vN; v ++)

    {

        if(g[u][v] && !chk[v])

        {

            chk[v] = true;

            if( yM[v] == -1 || SearchPath(yM[v]))

            {

                yM[v] = u, xM[u] = v;

                return true;

            }

        }

    }

    return false;

}



int MaxMatch()

{

    int u, ret = 0;

    memset( xM, -1, sizeof xM);

    memset( yM, -1, sizeof yM);

    for( u = 1; u <= uN; u ++)

    {

        if( xM[u] == -1)

        {

            memset( chk, false, sizeof chk);

            if(SearchPath(u)) ret ++;

        }

    }

    return ret;

}



void ReadGragh()

{

    vN = 1, uN = 1;

    memset( xr, 0, sizeof xr);

    memset( yc, 0, sizeof yc);

    memset( g, false, sizeof g);

    for( int i = 0; i < R; i ++)

    {

        scanf( "%s", map[i]);

    }

    for( int i = 0; i < R; i ++)

    {

        for( int j = 0; j < C; j ++)

        {

            if( map[i][j] == '*')

            {

                xr[i][j] = uN;

                while( map[i][j] == '*')

                {

                    xr[i][j] = uN;

                    j ++;

                }

                uN ++;

            }

        }

    }



    for( int j = 0; j < C; j ++)

    {

        for( int i = 0; i < R; i ++)

        {

            if( map[i][j] == '*')

            {

                yc[i][j] = vN;

                while( map[i][j] == '*')

                {

                    yc[i][j] = vN;

                    i ++;

                }

                vN ++;

            }

        }

    }

    for( int i = 0; i < R; i ++)

        for( int j = 0; j < C; j ++)

        {

            if(map[i][j] == '*')

            {

                g[xr[i][j]][yc[i][j]] = true;

            }

        }



}



int main()

{

    while( scanf( "%d%d", &R, &C) == 2)

    {

        ReadGragh();

        printf( "%d\n", MaxMatch());

    }

    return 0;

}

 

 

你可能感兴趣的:(Field)