二分图 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;

}

 

你可能感兴趣的:(robot)