二分图 zju 1654 Place the Robots

zju 1654 Place the Robots
//zju 1654 Place the Robots

//题意:
//给出一个地图,有空地,草地,墙壁。
//要在空地上放能像4个方向发射激光的机器人,
//问最多能放多少个,机器人不能对打

//思路:
//分别对横向和纵向分块。分块方法:对从空地开始
//相连的上下或左右没有没墙隔开的区域 标号;横竖要分开标号,
//分为二部图的两部分,求最大匹配即为答案
//这样子一块空地上放上机器人就可以对应横竖两个区域
//让所有横竖区域达到最大匹配即在对应的空地上放上机器人,
//所以最大匹配数就是最多能放的机器人数

//注意点:
//dfs寻找增广路时,寻找失败时记得加上return false;

#define comein freopen("in.txt", "r", stdin);
#include <stdio.h>
#include <string.h>

#define N 55

char map[N][N];
int rowSet[N][N], colSet[N][N];
bool road[N*N][N*N], vis[N*N];
int right[N*N];

bool dfs(int root, int colCnt)
{
    for(int i = 1; i <= colCnt; ++i)
    {
        if(vis[i] == false && road[root][i] == true)
        {
            vis[i] = true;
            if(right[i] == 0 || dfs(right[i], colCnt))
            {
                right[i] = root;
                return true;
            }
        }
    }
    return false;   //记得return false
}

int hungary(int rowCnt, int colCnt)
{
    int cnt = 0;
    memset(right, 0, sizeof(right));
    for(int i = 1; i <= rowCnt; ++i)
    {
        memset(vis, false, sizeof(vis));
        if(dfs(i, colCnt))
            cnt++;
    }
    return cnt;
}

int main()
{
    int n_case, row, col;
    scanf("%d", &n_case);
    for(int t = 1; t <= n_case; ++t)
    {
        scanf("%d%d", &row, &col);
        for(int i = 0; i < row; ++i)
            scanf("%s", map[i]);
        int rowCnt = 0, colCnt = 0;
        for(int i = 0; i < row; ++i)
        {
            int j = 0;
            while(j < col)
            {
                if(map[i][j] == 'o')
                {
                    rowCnt++;
                    while(j < col && map[i][j] != '#')
                        rowSet[i][j++] = rowCnt;
                }
                else
                    j++;
            }
        }
        for(int i = 0; i < col; ++i)
        {
            int j = 0;
            while(j < row)
            {
                if(map[j][i] == 'o')
                {
                    colCnt++;
                    while(j < row && map[j][i] != '#')
                        colSet[j++][i] = colCnt;
                }
                else
                    j++;
            }
        }
        memset(road, false, sizeof(road));
        for(int i = 0; i < row; ++i)
            for(int j = 0; j < col; ++j)
                if(map[i][j] == 'o')
                    road[rowSet[i][j]][colSet[i][j]] = true;
        int cnt = hungary(rowCnt, colCnt);
        printf("Case :%d\n%d\n", t, cnt);
    }
    return 0;
}

 

posted @ 2012-07-30 22:15  gabo  阅读(217)  评论(0编辑  收藏  举报