IT民工
加油!

这道题是最小点覆盖的题,用最少的木板将泥地覆盖。我们建图时将横的线段看成二分图的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;
}

 

 

posted on 2012-04-05 23:59  找回失去的  阅读(347)  评论(0编辑  收藏  举报