6802 車的放置 0x60「图论」例题

描述

给定一个N行M列的棋盘,已知某些格子禁止放置。问棋盘上最多能放多少个不能互相攻击的車。車放在格子里,攻击范围与中国象棋的“車”一致。N,M≤200。

输入格式

第一行为n,m,t(表示有t个禁止的格子)

第二行到t+1行为x,y,分别表示禁止格子所在的位置,x为第x行,y为第y列,行列编号从1开始。

输出格式

一个整数,表示最多能放多少个車。

样例输入

8 8 0

样例输出

8
        </article>

题解

把行、列看成节点

1要素:行节点、列节点只能放一个

0要素:行节点之间没有边,列节点之间也没有

所以建二分图跑最大匹配,时间复杂度\(O((n+m)nm)\)

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
rg T data=0,w=1;rg char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef long long ll; co int N=201;
int n,m,t,ans,fa[N];
bool a[N][N],v[N];
bool dfs(int x){
for(int y=1;y<=m;++y){
if(a[x][y]||v[y]) continue;
v[y]=1;
if(!fa[y]||dfs(fa[y])){
fa[y]=x;
return 1;
}
}
return 0;
}
int main(){
read(n),read(m),read(t);
while(t--) a[read<int>()][read<int>()]=1;
for(int i=1;i<=n;++i){
memset(v,0,sizeof v);
ans+=dfs(i);
}
printf("%d\n",ans);
return 0;
}

6B24 Place the Robots 0x6B「图论」练习

描述

给出一个地图(网格),格子分为空地,草地,墙壁。要在空地上放能向上下左右4个方向发射激光的机器人。墙壁能挡住激光,草地不能挡住激光也不能放机器人。问最多能放多少个,使得机器人不能对打。

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.

输入格式

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.

输出格式

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.

样例输入

2
4 4
o***
*###
oo#o
***o
4 4
#ooo
o#oo
oo#o
***#

样例输出

Case :1
3
Case :2
5

来源

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1654

        </article>

题解

几乎就是每行每列只能放一个。现在有了墙壁,相当于多拆出来一些点。并且墙壁和草地让连边少了一点。

时间复杂度\(O(n^3)\)

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
rg T data=0,w=1;rg char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef long long ll;
using namespace std; co int N=51;
int n,m,fa[N][N],fb[N][N],f[N*N],id;
char s[N][N];
vector<int> e[N*N];
bitset<N*N> v;
il void add(int x,int y){
e[x].push_back(y);
}
bool dfs(int x){
for(unsigned i=0;i<e[x].size();++i){
int y=e[x][i];
if(v[y]) continue;
v[y]=1;
if(!f[y]||dfs(f[y])){
f[y]=x;
return 1;
}
}
return 0;
}
void Place_the_Robots(){
read(n),read(m);
for(int i=1;i<=n;++i) scanf("%s",s[i]+1);
int a=0;
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)if(s[i][j]!='#')
fa[i][j]=a+=j==1||s[i][j-1]=='#';
int b=a;
for(int j=1;j<=m;++j)
for(int i=1;i<=n;++i)if(s[i][j]!='#')
fb[i][j]=b+=i==1||s[i-1][j]=='#';
for(int i=1;i<=b;++i) e[i].clear(),f[i]=0;
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)if(s[i][j]=='o')
add(fa[i][j],fb[i][j]),add(fb[i][j],fa[i][j]);
int ans=0;
for(int i=1;i<=a;++i){
v<<=b;
ans+=dfs(i);
}
printf("Case :%d\n%d\n",++id,ans);
}
int main(){
for(int t=read<int>();t--;) Place_the_Robots();
return 0;
}

CH6802 車的放置 和 CH6B24 Place the Robots的更多相关文章

  1. CH6802 車的放置

    原题链接 和棋盘覆盖(题解)差不多. 将行和列看成\(n+m\)个节点,且分属两个集合,如果某个节点没有被禁止,则行坐标对应节点向列坐标对应节点连边,然后就是求二分图最大匹配了. #include&l ...

  2. AcWing P373 車的放置

    Analysis 这道题是二分图匹配,设可以放車的的地方的坐标为(i,j),则连一条i到j的有向边(注意是有向边),然后再跑匈牙利算法就好了.时间复杂度是O(nm(n+m)),在1≤n,m≤200的情 ...

  3. 【题解】宫廷守卫 [P1263]

    [题解]宫廷守卫 [P1263] 传送门:宫廷守卫 \([P1263]\) [题目描述] 给出一个 \(n*m\) 的方格图,分别用整数 \(0,1,2\) 表示空地.陷阱.墙,空地上可以放置守卫,如 ...

  4. P3355 骑士共存问题【洛谷】(二分图最大独立集变形题) //链接矩阵存图

    展开 题目描述 在一个 n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘上某些方格设置了障碍,骑士不得进入 对于给定的 n*n 个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可 ...

  5. 总结-一本通提高篇&算竞进阶记录

    当一个人看见星空,就再无法忍受黑暗 为了点亮渐渐沉寂的星空 不想就这样退役 一定不会鸽の坑 . 一本通提高篇 . 算竞进阶 . CDQ & 整体二分 . 平衡树 . LCT . 字符串 . 随 ...

  6. Robots.txt 编写

    搜索引擎Robots协议,是放置在网站根目录下robots.txt文本文件,在文件中可以设定搜索引擎蜘蛛爬行规则.设置搜索引擎蜘蛛Spider抓取内容规则.下面Seoer惜缘举例robots写法规则与 ...

  7. 【CH6802】车的放置

    题目大意:给定一个 N*M 的棋盘,棋盘上有些点不能放置任何东西,现在在棋盘上放置一些车,问最多可以放置多少个车而不会互相攻击. 题解:将放置一个车看作连接一条无向边,因为每一行和每一列之间只能放置一 ...

  8. bzoj4807 車

    题目大意: Description 众所周知,車是中国象棋中最厉害的一子之一,它能吃到同一行或同一列中的其他棋子.車跟車显然不能在一起打 起来,于是rly一天又借来了许多许多的車在棋盘上摆了起来……他 ...

  9. Python 基礎 - 元組與簡易購物車實做

    tuple(元組) 其實跟列表差不多,也是存一組數,只不過是它一旦建立了,就不能修改了,只能做 切片 跟 查詢,所以只叫 只讀列表 語法: name = ("Rogers", &q ...

随机推荐

  1. WCF基础之数据协定

    数据协定最重要的当然就是DataContract和DataMember.这两个特性能应用到类.结构和枚举.这个两个特性跟服务契约的特点是一样的,只有被DataContract标记的类和类中被标记Dat ...

  2. Python菜鸟之路:Python基础(二)

    一.温故而知新 1. 变量命名方式 旧的方式: username = 'xxxx' password = 'oooo' 新的方式: username, password = 'xxxx', 'oooo ...

  3. 15.Django添加一个功能模块的步骤(和SpringMVC类比)

    这里介绍如何在Django里新建一个模块,这个例子还是最简单的例子 通过浏览器访问 http://localhost:8000/hello/然后返回一个欢迎页 我是做java web出身的,这里用py ...

  4. activiti基础--0------------------------------生成23张表

    1.工作流activiti.cfg.xml配置文件 <beans xmlns="http://www.springframework.org/schema/beans" xm ...

  5. 排序算法-python版

    总结了一下常见集中排序的算法 归并排序 归并排序也称合并排序,是分治法的典型应用.分治思想是将每个问题分解成个个小问题,将每个小问题解决,然后合并. 具体的归并排序就是,将一组无序数按n/2递归分解成 ...

  6. C#快速入门笔记(1)——基础语法

    C#快速入门笔记(1)——基础语法 总体框架:

  7. iOS 开发规范

    公司来了大牛  是绝好的学习机会 今天分享了我们一个代码规范 比如UITableViewCell 1.首先根据这个cell 需要的数据源 建一个数据model ,只针对于 该cell  好处:数据独立 ...

  8. ajax的原理及使用

    ajax并非是一门新的技术,而是现有技术的一种新的组合用法,即是结合异步javascript和XML,它是一种创建快速动态网页的技术.其中,异步javascript是相对于同步而言的,同步模式通常称为 ...

  9. debian下使用ft232为stm32f429i-discovery烧写uboot和uImage

    操作系统:debian 软件: openocd  minicom 硬件:  MiniUSB线.stm32f429i-discovery, WaveShare FT232串口模块(可以在淘宝上买到) 关 ...

  10. Spring Cloud之Eureka自我保护环境搭建

    Eureka详解 服务消费者模式 获取服务 消费者启动的时候,使用服务别名,会发送一个rest请求到服务注册中心获取对应的服务信息,让后会缓存到本地jvm客户端中,同时客户端每隔30秒从服务器上更新一 ...