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
“ 这一行就仅仅能放一个,问最多能放多少个机器人?

刚学了二分图,二分图的水题做了有几个。不须要来练手了,对于这个题。看懂题意后知道是二分图的最大独立集合。可是难点是怎么建图。

昨天晚上看的这道题目,一点思路也没有。回宿舍后想了又想,想到怎么建图,今天敲了。WA n次,查了一下题解。建图方式没有错,仅仅是我漏了一点就是,仅仅进行了横向分块当做X集合,剩余点默觉得Y集合。

。。

思路:採用分块的思想进行建图。什么是块?联系题意。块就攻击范围能够达到的就是一块,“ o*oo ”这就是块,并且是一块,“ *o#o
”,这就是两块。 通俗点说就是,地图的这一行被墙隔开且有空地的连续区域称作”块“。当然,依照题意。在一个块中,最多仅仅能放置一个机器人,纵向也是如此分块,对块进行编号。横向分块的全部编号为X集合,纵向的全部编号为Y集合,当然存在同一个” o“点被两次编号过,那么建一条边就好了。

Result Accepted    ID 1654   Language   C++   Time   60   Memery    26720
include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <math.h>
#define init(a) memset(a,0,sizeof(a))
#define PI acos(-1,0)
using namespace std;
const int maxn = 55;
const int maxm = 2600;
#define lson left, m, id<<1
#define rson m+1, right, id<<1|1
#define min(a,b) (a>b)?b:a
#define max(a,b) (a>b)?a:b
int mar[maxn][maxn],mac[maxn][maxn];
int G[maxm][maxm];
int line[maxm];
char MAP[maxn][maxn];
bool vis[maxm];
int X,Y;
int DFS(int u)
{
    for(int v = 1;v<=Y;v++)
    {
        if(G[u][v]==1 && !vis[v])
        {
            vis[v] = 1;
            if(line[v]==-1 || DFS(line[v]))
            {
                line[v] = u;
                return 1;
            }
        }
    }
    return 0;
}
int K_M()
{
    memset(line,-1,sizeof(line));
    int ans = 0;
    for(int i = 1;i<=X;i++)
    {
        init(vis);
        ans += DFS(i);
    }
    return ans;
}
void Creat_G(int n,int m)
{
    for(int i = 0;i<n;i++)  //横向分块当做X集合
        {
            for(int j = 0;j<m;j++)
            {
                if(MAP[i][j]==‘o‘)
                {
                    X++;
                    while(j<m && MAP[i][j]!=‘#‘)
                    {
                        mar[i][j]=X;//处于同一块的空地或草地编号是一样的
                        j++;
                    }
                }
            }
        }
        for(int i = 0;i<m;i++)//纵向分块当做Y集合
        {
            for(int j = 0;j<n;j++)
            {
                if(MAP[j][i]==‘o‘)
                {
                    Y++;
                    while(j<n && MAP[j][i]!=‘#‘)
                    {
                        mac[j][i] = Y;
                        j++;
                    }
                }
            }
        }
}
int main()
{
    int t,n,m;
    scanf("%d",&t);
    for(int Case = 1;Case <=t;Case++)
    {
        init(G); init(mar);init(mac);
        X = 0, Y = 0;

        scanf("%d%d",&n,&m);
        for(int i = 0;i<n;i++)
            scanf("%s",MAP[i]);

        Creat_G(n,m);//分块

        for(int i = 0;i<n;i++) //建图
        {
            for(int j = 0;j<m;j++)
            {
                if(MAP[i][j]==‘o‘)
                {
                    G[mar[i][j]][mac[i][j]] = 1;//构建块与块的连通
                }
            }
        }
       int ans = K_M();
        printf("Case :%d\n%d\n",Case,ans);
    }
    return 0;
}
时间: 2024-10-08 00:57:42

ZOJ 1654 Place the Robots建图思维(分块思想)+二分匹配的相关文章

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

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

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

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

HDU 4292 Food (建图思维 + 最大流)

(点击此处查看原题) 题目分析 题意:某个餐馆出售f种食物,d种饮料,其中,第i种食物有fi份,第i种饮料有di份:此时有n个人来餐馆吃饭,这n个人必须有一份食物和一份饮料才会留下来吃饭,否则,他将离去,而且每个人只吃某几种食物和饮料,如果某个人留下来,那么必须提供一份他吃的食物和一份他吃饮料,问在这种情况下,最多可以招待多少人. 思路:这类的题目我总结为:最大流受到两个互不影响的物体的影响,这类题目为最大流题目,建边如下: 1)由源点向每一种食物i代表的结点建一条容量为fi的边 2)将每个顾客

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(最大匹配)

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 ro

ZOJ 1654 Place the Robots

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

HDU 4370 0 or 1(spfa+思维建图+计算最小环)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4370 题目大意:有一个n*n的矩阵Cij(1<=i,j<=n),要找到矩阵Xij(i<=1,j<=n)满足以下条件: 1.X 12+X 13+...X 1n=1  2.X 1n+X 2n+...X n-1n=1  3.for each i (1<i<n), satisfies ∑X ki (1<=k<=n)=∑X ij (1<=j<=n). 举个例子

【二分图匹配入门专题1】poj3686 【km+思维建图】

The Windy's Description The Windy's is a world famous toy factory that owns M top-class workshop to make toys. This year the manager receives N orders for toys. The manager knows that every order will take different amount of hours in different works

POJ 3020 Antenna Placement(二分图建图训练 + 最小路径覆盖)

题目链接:http://poj.org/problem?id=3020 Antenna Placement Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6692   Accepted: 3325 Description The Global Aerial Research Centre has been allotted the task of building the fifth generation of mobi