ZOJ 1654 Place the Robots(最大匹配)

Robert is a famous engineer. One day he was given a task by his boss. The background of the task was the following:

Given a map consisting of square blocks. There were three kinds of blocks: Wall, Grass, and Empty. His boss wanted to place as many robots as possible in the map. Each robot held a laser weapon which could shoot to four directions (north, east, south, west)
simultaneously. A robot had to stay at the block where it was initially placed all the time and to keep firing all the time. The laser beams certainly could pass the grid of Grass, but could not pass the grid of Wall. A robot could only be placed in an Empty
block. Surely the boss would not want to see one robot hurting another. In other words, two robots must not be placed in one line (horizontally or vertically) unless there is a Wall between them.

Now that you are such a smart programmer and one of Robert‘s best friends, He is asking you to help him solving this problem. That is, given the description of a map, compute the maximum number of robots that can be placed in the map.

Input

The first line contains an integer T (<= 11) which is the number of test cases.

For each test case, the first line contains two integers m and n (1<= m, n <=50) which are the row and column sizes of the map. Then m lines follow, each contains n characters of ‘#‘, ‘*‘, or ‘o‘ which represent Wall, Grass, and Empty, respectively.

Output

For each test case, first output the case number in one line, in the format: "Case :id" where id is the test case number, counting from 1. In the second line just output the maximum number of robots that can be placed in that map.

Sample Input

2

4 4

o***

*###

oo#o

***o

4 4

#ooo

o#oo

oo#o

***#

Sample Output

Case :1

3

Case :2

5

题意:机器人能攻击跟它所在同一行跟列的全部东西,仅仅有‘o‘才干放机器人,‘#‘表示墙壁,能挡住机器人的攻击(意味着墙壁之间能放机器人),要你求出n*m的矩阵上能放多少机器人

思路:最大独立集。可惜眼下没有不论什么算法能求出最大独立集。

那么我们换一个思路,之前做过POJ3041,能够类似地做这道题,可是本题中的墙壁为我们的标记提供了难度。那么我么能够用xs数组看做X集合(表示每行中的‘o‘的位置。假设不相容则标记为同一个数),同理做一个列的ys数组!

相应下来。在每个‘o‘上连接两集合的点形成边,我们发现符合题目的每条边之间不能有公共点,所以就转化为了最小边覆盖的问题,刚好就是最大匹配!

AC代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int N = 55;
const int maxn=2600;

int link[maxn][maxn];
int xs[N][N],ys[N][N];
int col[maxn],vis[maxn];
int mx,my;

int n,m;

int match(int x)
{
    int i;
    for(i=1;i<=my;i++){
        if(link[x][i]&&!vis[i])
        {
            vis[i]=1;
            if(!col[i]||match(col[i]))
            {
                col[i]=x;
                return 1;
            }
        }
    }
    return 0;
}

char str[N][N];

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("in.cpp","r",stdin);
    freopen("out.cpp","w",stdout);
    #endif // ONLINE_JUDGE
    int t;
    scanf("%d",&t);
    int cas=1;
    while(t--)
    {
        int cnt=1;
        scanf("%d %d",&n,&m);
        memset(xs,0,sizeof(xs));
        memset(ys,0,sizeof(ys));
        getchar();
        for(int i=0;i<n;i++)
        {
            scanf("%s",str[i]);
            for(int j=0;j<m;j++)
            {
                if(str[i][j]==‘o‘)
                {
                    xs[i][j]=cnt;
                }

                else if(str[i][j]==‘#‘)
                    cnt++;
            }
            cnt++;
        }
        int maxx=cnt;
        mx=cnt;
        cnt=1;
        for(int j=0;j<m;j++)
        {
            for(int i=0;i<n;i++)
            {
                if(str[i][j]==‘o‘)
                    ys[i][j]=cnt;
                else if(str[i][j]==‘#‘)
                    cnt++;
            }
            cnt++;
        }
        my=cnt;
        memset(link,0,sizeof(link));
        memset(col,0,sizeof(col));
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                if(str[i][j]==‘o‘)
                {
                    link[xs[i][j]][ys[i][j]]=1;
                }
            }
        }

        int tot=0;
        for(int i=1;i<=mx;i++)
        {
            memset(vis,0,sizeof(vis));
            if(match(i))tot++;
        }
        printf("Case :%d\n",cas++);
        printf("%d\n",tot);
    }
    return 0;
}
时间: 2024-11-08 13:35:13

ZOJ 1654 Place the Robots(最大匹配)的相关文章

ZOJ 1654 - Place the Robots (二分图最大匹配)

题意:在一个m*n的地图上,有空地,草和墙,其中空地和草能穿透攻击光线,而墙不能.每个机器人能够上下左右攻击,问在地图上最多能放多少个不互相攻击的机器人. 这个题和HDU 1045 -  Fire Net很像.很容易联想到对每个点编号然后互相攻击的点连边再求图的最大独立集,但是这个题数据量太多,超时. 换个思路. 将每个机器人可以攻击到的区域在横和竖方向上分开,这样当横和竖攻击方向都确定时就可以确定一个机器人的放置位置,而在同一个横或竖的攻击区域内不可以再放置机器人. 这样我们把原图上的空地按照

ZOJ 1654 Place the Robots 二分图最大匹配

唉,又是神一样的建模,表示完全想不到. 题意是给你一块地,上面有空地,草地,障碍三种地形,然后让你在上面放机器人,机器人只能放在空地上.机器人会向上下左右四个方向发出攻击,机器人的攻击可以穿过草地但是无法穿过障碍.问你在不会是机器人相互攻击的前提下,最多能放多少个机器人. 我觉得大致的思路应该是这样的,首先会想当然的想到把能够相互攻击到的空地连边,然后求最大独立集,但最大独立集不好求,所以要想办法把它转化成最大匹配问题. 所以要想办法把空地变成边,首先一块空地肯定是有他的横坐标和纵坐标,可以表示

ZOJ 1654 Place the Robots (二分匹配 )

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=654 Robert is a famous engineer. One day he was given a task by his boss. The background of the task was the following: Given a map consisting of square blocks. There were three kinds of

ZOJ 1654 Place the Robots

题目大意: 在空地上放置尽可能多机器人,机器人朝上下左右4个方向发射子弹,子弹能穿过草地,但不能穿过墙, 两个机器人之间的子弹要保证互不干扰,求所能放置的机器人的最大个数 每个机器人所在的位置确定了,那么对应的横向和竖向子弹能到达的空地就全部被覆盖了 我们将横向所能连接在一块的空地区域标上同一个标号 比如o*o#o , 就可标号为10102因为1,3空地中间的草地不影响子弹的穿越 同理,我们将竖向的所能连接在一块的空地区域标上同一个标号 那么就可以建立一个横向到达竖向的二部图匹配 每次成功匹配一

ZOJ 1654 Place the Robots建图思维(分块思想)+二分匹配

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=654 AC一百道水题,不如AC一道难题来的舒服. 题意:一个n*m地图.*代表草地,#代表墙,o代表空地,要再图中的o处放机器人,机器人能够攻击(上下左右)4个方向,攻击范围无限长,并且机器人不能相互攻击,草地不能放置机器人,且机器人的攻击能够穿过草地,可是机器人的攻击不能穿过墙,比方 "   *o#o  "这一行就能够放两个机器人," o*oo

ZOJ 1364 Machine Schedule(二分图最大匹配)

题意 机器调度问题 有两个机器A,B A有n种工作模式0...n-1 B有m种工作模式0...m-1 然后又k个任务要做 每个任务可以用A机器的模式i或b机器的模式j来完成 机器开始都处于模式0 每次换模式时都要重启 问完成所有任务机器至少重启多少次 最基础的二分图最大匹配问题 对于每个任务把i和j之间连一条边就可以构成一个二分图 那么每个任务都可以对应一条边 那么现在就是要找最少的点 使这些点能覆盖所有的边 即点覆盖数 又因为二分图的点覆盖数 = 匹配数 那么就是裸的求二分图最大匹配问题了 两

ZOJ 3316 Game 一般图最大匹配带花树

一般图最大匹配带花树: 建图后,计算最大匹配数. 如果有一个联通块不是完美匹配,先手就可以走那个没被匹配到的点,后手不论怎么走,都必然走到一个被匹配的点上,先手就可以顺着这个交错路走下去,最后一定是后手没有路可走,因为如果还有路可走,这一条交错路,就是一个增广路,必然有更大的匹配. Game Time Limit: 1 Second      Memory Limit: 32768 KB Fire and Lam are addicted to the game of Go recently.

ACM -二分图题目小结(更新中)

暂时只包括与最大匹配相关的问题. 求最大独立集,最小路径覆盖等等大多数题目都可以转化为求最大匹配用匈牙利算法解决. 1.最大匹配(边集) 此类问题最直接,直接用匈牙利算法即可. HDU 2063  过山车 http://acm.hdu.edu.cn/showproblem.php?pid=2063 二分图最大匹配模版题. ZOJ 1654 - Place the Robots http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode

二分图学习

图论中的难见就是建图然后套用算法. 特点: 仅仅能一一相应,即XX仅仅能有一个人. 先来一个比較好的入门资料二分图最大匹配 參考 二分图建图方法 算法的思路是不停的找增广路径, 并添加匹配的个数,增广路径顾名思义是指一条能够使匹配数变多的路径,在匹配问题中,增广路径的表现形式是一条"交错路径",也就是说这条由图的边组成的路径. 它的第一条边是眼下还没有參与匹配的,第二条边參与了匹配.第三条边没有..最后一条边没有參与匹配,而且始点和终点还没有被选择过.这样交错进行,显然他有奇数条边.