zoj1654 Place the Robots

题目描述:

Robert 是一个著名的工程师。一天,他的老板给他分配了一个任务。任务的背景是:给定一

个m×n 大小的地图,地图由方格组成,在地图中有3 种方格-墙、草地和空地,他的老板希望

能在地图中放置尽可能多的机器人。每个机器人都配备了激光枪,可以同时向四个方向(上、下、

左、右)开枪。机器人一直待在最初始放置的方格处,不可移动,然后一直朝四个方向开枪。激

光枪发射出的激光可以穿透草地,但不能穿透墙壁。机器人只能放置在空地。当然,老板不希望

机器人互相攻击,也就是说,两个机器人不能放在同一行(水平或垂直),除非他们之间有一堵墙

格开。

给定一张地图,你的程序需要输出在该地图中可以放置的机器人的最大数目。

思路:

以样例解释

在问题的原型中,草地,墙这些信息不是本题所关心的,本题关心的只是空地和空地之间的联系。因此,很自然想到了下面这种简单的模型:以空地为顶点,在有冲突的空地间连边。

把所有的空地用数字标明,得到a图:

把所有有冲突的空地间用边连接后得到图(b):

于是,问题转化为求图的最大独立集问题:求最大顶点集合,集合中所有顶点互不连接(即互不冲突)。但是最大点独立集问题是一个NP 问题,没有有效的算法能求解。

————————————————————————————————————————————————————————————————————————

将每一行被墙隔开、且包含空地的连续区域称作“块”。显然,在一个块之中,最多只能放一个机器人。把这些块编上号,如图7.25(a)所示。需要说明的是,最后一行,即第4 行有两个空地,但这两个空地之间没有墙壁,只有草地,所以这两个空地应该属于同一“块”。同样,把竖直方向的块也编上号,如图7.25(b)所示。

把每个横向块看作二部图中顶点集合X 中的顶点,竖向块看作集合Y 中的顶点,若两个块有公共的空地(注意,每两个块最多有一个公共空地),则在它们之间连边。例如,横向块2 和竖向块1 有公共的空地,即(2, 0),于是在X 集合中的顶点2 和Y 集合中的顶点1 之间有一条边。这样,问题转化成一个二部图,如图7.25(c)所示。由于每条边表示一个空地(即一个横向块和一个竖向块的公共空地),有冲突的空地之间必有公共顶点。例如边(x1, y1)表示空地(0, 0)、边(x2, y1)表示空地(2, 0),在这两个空地上不能同时放置机器人。所以问题转化为在二部图中找没有公共顶点的最大边集,这就是最大匹配问题。

以上面给的样例的构造结果:

匈牙利算法 O( VE )

//题目详解描述转自http://m.blog.csdn.net/blog/u014141559/44409255

#include<cstdio>

#include<cmath>

#include<cstring>

#include<iostream>

#include<algorithm>

#include<queue>

#include<vector>

//#include<map>

#include<stack>

#pragma comment(linker,"/STACK:102400000,102400000")

#define pi acos(-1.0)

#define EPS 1e-6

#define INF (1<<24)

using namespace std;

int m,n;

char map[55][55];  //地图

int from[2555];   //from[y]表示与Yi匹配的X顶点

bool use[2555];

int xs[55][55],ys[55][55];  //水平方向上块的编号,垂直方向上块的编号

vector<int>g[2555];   //g[i]表示与左边点i相连的右边的点

int nx,ny;   //水平方向上块的个数,垂直方向上块的个数

bool match(int x)

{

for(int i=0;i<g[x].size();i++)

{

if(!use[g[x][i]])

{

use[g[x][i]]=true;

if(from[g[x][i]]==-1||match(from[g[x][i]]))

{

from[g[x][i]]=x;

return true;

}

}

}

return false;

}

int hungary()

{

int tot=0;

memset(from,255,sizeof(from));

for(int i=1;i<=nx;i++)

{

memset(use,0,sizeof(use));

if(match(i)) tot++;

}

return tot;  //最大匹配数

}

/*二分图最大匹配*/

/*匈牙利算法*/

int main()

{

int T,k;

scanf("%d",&T);

for(k=1;k<=T;k++)

{

scanf("%d %d",&m,&n);

getchar();

int i,j;

for(i=0;i<m;i++)

{

gets(map[i]);

}

/*  for(i=0;i<m;i++)

{

puts(map[i]);

}*/

nx=ny=0;

memset(xs,0,sizeof(xs));

memset(ys,0,sizeof(ys));

int flag;

for(i=0;i<m;i++)  //横向编号

{

flag=0;

for(j=0;j<n;j++)

{

if(map[i][j]==‘o‘)

{

if(flag!=1) nx++;

flag=1;

xs[i][j]=nx;

}

else if(map[i][j]==‘#‘) flag=0;

}

}

for(j=0;j<n;j++) //纵向编号

{

flag=0;

for(i=0;i<m;i++)

{

if(map[i][j]==‘o‘)

{

if(flag!=1) ny++;

flag=1;

ys[i][j]=ny;

}

else if(map[i][j]==‘#‘) flag=0;

}

}

/*x,y方向的编号分别为二分图一边点*/

for(i=0;i<=nx;i++) g[i].clear();

for(i=0;i<m;i++)

{

for(j=0;j<n;j++)

{

if(xs[i][j]&&ys[i][j])  //两个编号有交叉,,

{

g[xs[i][j]].push_back(ys[i][j]);  //有关系

}

}

}

printf("Case :%d\n",k);

printf("%d\n",hungary());

}

return 0;

}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-11 07:32:58

zoj1654 Place the Robots的相关文章

ZOJ1654 Place the Robots(二分图最大匹配)

二分图最大匹配也叫二分图最大边独立数,就是二分图中最多能取出两两不相邻的边的数目. 如果题目没有墙,那就是一道经典的二分图最大匹配问题: 把地图上的行和列分别作为点的X部和Y部,地图上每一块空地看作边,边的两个端点就是它所在的x行y列.这样,求最大边独立集即可. 而这一题有墙,然后我不会了.. 其实这题的建模也是一样的,也是行和列作为点,空地作为边: 对于每一行把被墙分隔的每一块连通的区域缩成一点,列也一样: 行缩成的点作为X部,列Y部: 某行连通区域最多就只能在区域内某一块空地放机器人,列也是

ZOJ1654.Place the Robots放置机器人——二部图最大匹配(hungary算法)

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=654 题目描述: Robert 是一个著名的工程师.一天,他的老板给他分配了一个任务.任务的背景是:给定一 个m×n 大小的地图,地图由方格组成,在地图中有3 种方格-墙.草地和空地,他的老板希望 能在地图中放置尽可能多的机器人.每个机器人都配备了激光枪,可以同时向四个方向(上.下. 左.右)开枪.机器人一直待在最初始放置的方格处,不可移动,然后一直朝四个方向开枪.激 光枪发射

Python 爬虫-Robots协议

2017-07-25 21:08:16 一.网络爬虫的规模 二.网络爬虫的限制 ? 来源审查:判断User‐Agent进行限制 检查来访HTTP协议头的User‐Agent域,只响应浏览器或友好爬虫的访问? 发布公告:Robots协议 告知所有爬虫网站的爬取策略,要求爬虫遵守 三.Robots 协议 作用:网站告知网络爬虫哪些页面可以抓取,哪些不行形式:在网站根目录下的robots.txt文件 如果网站不提供Robots协议则表示该网站允许任意爬虫爬取任意次数. 类人类行为原则上可以不遵守Rob

robots.txt的介绍和写作

目前很多网站管理者似乎对robots.txt并没有引起多大重视,甚至不知道这么一个文件的作用.本来应该保密的信息被爬虫抓取了,公布在公网上,本应该发布到公网的信息却迟迟不被搜索引擎收录.所以下面这篇文章,就来介绍robots.txt的作用和写作 robots.txt基本介绍 robots 是一个纯文本文件,是用来告诉搜索引擎:当前这个网站上哪些部分可以被访问.哪些不可以,robots文件是存放在网站根目录下的一个纯文本文件.当搜索引擎访问一个网站时,它首先会检查该网站根目录下是否存在robots

Place the Robots 需要较强的建图能力

Place the Robots 思路:在任意一个点格子放机器人,那么它所在的行和列被控制了.我们对每一行或每一列连续的空地(草地忽视)称之为块,给每一行和每一列的块标号, 每一行的快与每一列的快相交的话,才有只有一个交点.  我们把交点当边,把行块和列块连接起来.每一个空第都是一条边.详细细节见代码. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath&

django1.5添加robots.txt

方法一:(The best way) urlpatterns = patterns( (r’^robots\.txt$’, TemplateView.as_view(template_name=’robots.txt’, content_type=’text/plain’)), ) 其他: http://stackoverflow.com/questions/6867468/setting-up-mimetype-when-using-templateview-in-django

seo课程之robots.txt的格式

其实很多人刚刚开始从事seo的时候,根本就不知道什么是robots.txt,就算知道了也不懂得robots.txt的文件格式是什么,今天小编我就来和大家分享一下吧(本文来自于e良师益友网). "robots.txt"文件包含一条或更多的记录,这些记录通过空行分开(以CR,CR/NL, or NL作为结束符),每一条记录的格式如下所示: "<field>:<optional space><value><optionalspace>

UVA10599 - Robots(II)(变形的LIS)

题意:一个机器人在n * m的网格里面捡垃圾,机器人只能向右或向下走,求出能捡到的垃圾数量的最大值,有多少条路径可以达到最大值,以及输出其中一条路径. 思路:按照题意可以看出,因为机器人只能向右和向下走,所以纵坐标就不重要的,而横坐标是递增的.当将所有拥有垃圾的格子经过计算得到它的一维值(唯一的),得到一组的数组.那就可以转化为求最长上升子序列.但这个LIS的条件是mod(m)要大于前一个.计算数量时,当d[i] = d[j] + 1时,就相当于以i为结束时的最长上升子序列比以j结束时的最长上升

实例分析Robots.txt写法

题意:经典八数码问题 思路:HASH+BFS #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAXN = 500000; const int size = 1000003; typedef int State[9]; char str[30]; int state[9],goal[9]={