[ABC274G] Security Camera 3
Problem Statement
There is a grid with $H$ rows from top to bottom and $W$ columns from left to right. Let $(i, j)$ denote the square at the $i$-th row from the top and $j$-th column from the left.
Square $(i, j)$ is occupied by an obstacle if $S_{i,j}=$ #, and is empty if $S_{i,j}=$ ..
Takahashi will install some surveillance cameras in the grid.
A surveillance camera can be placed at a square without an obstacle, in one of the four directions: up, down, left, or right.
Multiple surveillance cameras may be placed at the same square.
Each surveillance camera monitors the square it is placed at, and the squares in the direction it is placed in, as far as there is no obstacle in between.
At least how many surveillance cameras are needed to monitor all squares without an obstacle?
Constraints
- $1 \leq H,W \leq 300$
- $S_{i,j}$ is
.or#.
Input
The input is given from Standard Input in the following format:
$H$ $W$
$S_{1,1}\ldots S_{1,W}$
$\vdots$
$S_{H,1}\ldots S_{H,W}$
Output
Print the answer.
Sample Input 1
3 3
...
.#.
...
Sample Output 1
4
For example, if we install two surveillance cameras at square $(1, 1)$ facing right and down, and another two at square $(3, 3)$ facing up and left, all squares without an obstacle will be monitored.
Sample Input 2
3 5
...##
.#...
...#.
Sample Output 2
5
For example, if we install two surveillance cameras at square $(1, 1)$ facing right and down, another at square $(3, 3)$ facing left, and another two at square $(2, 5)$ facing left and down, all squares without an obstacle will be monitored.
Note that the camera at square $(2, 5)$ facing left cannot monitor square $(2, 1)$, since there is an obstacle in between at square $(2, 2)$.
Sample Input 3
14 107
...........................................................................................................
...........................................................................................................
..#########..###....###########..###.......###...###########..####.......###...###########...###########...
..########..###....###########....###.....###...###########...#####......###..###########...###########....
..#######..###.....###.............###...###....###...........######.....###..###...........###............
..######..###......###..............###.###.....###...........###.###....###..###...........###............
..#####..###.......############......#####......############..###..###...###..###...........############...
..####....###......############.......###.......############..###...###..###..###...........############...
..###......###.....###................###.......###...........###....###.###..###...........###............
..##........###....###................###.......###...........###.....######..###...........###............
..#..........###...############.......###.......############..###......#####..############..############...
..............###...###########.......###........###########..###.......####...###########...###########...
...........................................................................................................
...........................................................................................................
Sample Output 3
91
最优化问题,在尝试了贪心,dp后,走向网络流。
首先一个监控有4个方向,但是只有两个方向有用。因为你在一个地方放置向右的监控,效果一定不差于在这个地方往右遇到的第一个障碍的前面或边界放置一个往左的监控。之后不妨设只有向下和向右的两种方向的监控。
另一个结论是,一个点会放向下的监控,当且仅当他位于上边界或者他上面是障碍,不然他的效果1肯定不如再往上一格去放。向右的监控同理。
最大流很难建图,考虑去求最小割。不妨把一个点拆成两个点,一个代表他是否放置往右的监控,一个代表他是否放置往下的监控。源点连向每一个代表是否放置往右监控的店,每一个代表是否放置往下的监控的点连向汇点,流量均为1。对于一个点,处理出他往上最近的一个可以放置的店,他往左最近的一个可以放置的店。这两个点至少要选一个,所以给这两个点分别代表的点中间连一条流量为正无穷的边。那么此时跑最大流,一条边断了,表示他放置往下/往右的监控。那么此时每个点代表的每条边,他的左右都至少1有一个点选了,也就代表这个点被覆盖了。
发现图是二分图,复杂度 \(O((HW)^{1.5})\)
#include<bits/stdc++.h>
using namespace std;
const int N=305,M=3*N*N+6;
int h,w,e_num(1),hd[M],s,t,l,r,q[M],v[M],k,vhd[M],x[N][N],y[N][N],ans;
struct edge{
int v,nxt,f;
}e[N*N*10];
int get(int x,int y)
{
return x*h+w;
}
void add_edge(int u,int v,int f)
{
// printf("%d %d %d\n",u,v,f);
e[++e_num]=(edge){v,hd[u],f};
hd[u]=e_num;
}
char str[N][N];
int bfs()
{
memset(v,0,sizeof(v));
q[l=r=1]=s,v[s]=1;
memcpy(hd,vhd,sizeof(hd));
while(l<=r)
{
for(int i=hd[q[l]];i;i=e[i].nxt)
{
if(!v[e[i].v]&&e[i].f)
{
// printf("%d %d %d\n",q[l],e[i].v,e[i].f);
v[e[i].v]=v[q[l]]+1;
q[++r]=e[i].v;
}
}
++l;
}
// for(int i=1;i<=t;i++)
// printf("%d ",v[i]);
// putchar('\n');
return v[t];
}
int dfs(int x,int flow)
{
if(x==t)
return flow;
int s=0;
for(int&i=hd[x];i;i=e[i].nxt)
{
if(v[e[i].v]==v[x]+1&&e[i].f)
{
int t=dfs(e[i].v,min(flow,e[i].f));
flow-=t,s+=t;
e[i].f-=t,e[i^1].f+=t;
if(!t)
v[e[i].v]=0;
if(!flow)
break;
}
}
return s;
}
int main()
{
scanf("%d%d",&h,&w) ;
s=2*h*w,t=2*h*w+1;
for(int i=0;i<h;i++)
scanf("%s",str[i]);
for(int i=0;i<h;i++)
{
for(int j=0;j<w;j++)
{
if(str[i][j]=='#')
continue;
k=i*w+j;
if(!i||str[i-1][j]=='#')
{
x[i][j]=k;
add_edge(s,k,1);
add_edge(k,s,0) ;
}
else
x[i][j]=x[i-1][j];
if(!j||str[i][j-1]=='#')
{
y[i][j]=k;
add_edge(k+h*w,t,1);
add_edge(t,k+h*w,0);
}
else
y[i][j]=y[i][j-1];
add_edge(x[i][j],y[i][j]+h*w,1e9);
add_edge(y[i][j]+h*w,x[i][j],0);
}
}
memcpy(vhd,hd,sizeof(hd));
while(bfs())
while(k=dfs(s,2e9))
ans+=k;
printf("%d",ans);
}
[ABC274G] Security Camera 3的更多相关文章
- ABC220H - Security Camera
考虑折半,将点按照标号是否 \(\le \frac{n}{2}\) 分成两个集合 \(S_1, S_2\). 首先原问题的形式有点奇怪,我们不妨统计没有被覆盖覆盖的边为偶数条的情况. 这样一来问题转化 ...
- Unity3D重要知识点
数据结构和算法很重要!图形学也很重要!大的游戏公司很看重个人基础,综合能力小公司看你实际工作能力,看你的Demo. 1.什么是渲染管道? 是指在显示器上为了显示出图像而经过的一系列必要操作. 渲染管道 ...
- Unity3D 面试题汇总
最先执行的方法是: 1.(激活时的初始化代码)Awake,2.Start.3.Update[FixUpdate.LateUpdate].4.(渲染模块)OnGUI.5.再向后,就是卸载模块(TearD ...
- Unity随机随学
1.什么是渲染管道? 是指在显示器上为了显示出图像而经过的一系列必要操作.渲染管道中的步骤很多,都要将几何物体从一个坐标系中变换到另一个坐标系中去. 主要步骤有: 本地坐标->视图坐标-> ...
- 越狱Season 1-Episode 15: By the Skin and the Teeth
Season 1, Episode 15: By the Skin and the Teeth -Pope: doctor...you can leave. 医生你得离开 -Burrows: It's ...
- U3D常用题
最先执行的方法是:1.(激活时的初始化代码)Awake,2.Start.3.Update[FixUpdate.LateUpdate].4.(渲染模块)OnGUI.5.再向后,就是卸载模块(TearDo ...
- Questions about UIUC and USC
Questions about UIUC and USC I am admitted to University of Illinois at Urbana-Champaign (UIUC) Prof ...
- Unity3D 面试ABC
最先执行的方法是: 1.(激活时的初始化代码)Awake,2.Start.3.Update[FixUpdate.LateUpdate].4.(渲染模块)OnGUI.5.再向后,就是卸载模块(TearD ...
- U3D 基础
千里之行,始于足下! 最先执行的方法是:1.(激活时的初始代码)Awake2.Start3.Update(FixUpdate,LateUpdate)4.渲染模块(OnGUI)5.再向后,就是卸载模块( ...
- Unity3d笔试题大全
1. [C#语言基础]请简述拆箱和装箱. 答: 装箱操作: 值类型隐式转换为object类型或由此值类型实现的任何接口类型的过程. 1.在堆中开辟内存空间. 2.将值类型的数据复制到堆中. ...
随机推荐
- MySQL 1130错误原因及解决方案
错误:ERROR 1130: Host 'http://xxx.xxx.xxx.xxx' is not allowed to connect to thisMySQL serve 错误1130:主机x ...
- K8S集群中使用JD KMS服务对敏感数据安全加密
基本概念 KMS,Key Management Service,即密钥管理服务,在K8S集群中,以驱动和插件的形式启用对Secret,Configmap进行加密.以保护敏感数据, 驱动和插件需要使用者 ...
- 《SQL与数据库基础》05. SQL-DCL
目录 DCL 用户管理 权限控制 本文以 MySQL 为例 DCL 用户管理 查询有哪些用户: 1. USE mysql; SELECT * FROM user; 2. SELECT * FROM m ...
- Solution Set -「ARC 116」(in progress)
「ARC 116A」Odd vs Even Link. 看 \(n\) 有多少 \(2\) 因子. // Problem: A - Odd vs Even // Contest: AtCoder - ...
- redis基本数据类型 List
127.0.0.1:6379> LPUSH test a (integer) 1 127.0.0.1:6379> LPUSH test b (integer) 2 127.0.0.1:63 ...
- Teamcenter RAC开发 GoToHelper
RAC开发,有时候会用到发送到我的Teamcenter 可以参考 com.teamcenter.rac.tcapps 包下 package com.teamcenter.rac.tracelinks; ...
- EQ 均衡器
EQ 的全称是 Equalizer,EQ 是 Equalizer 的前两个字母,中文名字叫做"均衡器".最早是用来提升电话信号在长距离的传输中损失的高频,由此得到一个各频带相对平衡 ...
- 11G RAC 11.2.0.1.0实例evict故障处理
Aix 7.1 参考文档: https://blogs.oracle.com/database4cn/rac Resolving ORA-481 and "terminating the i ...
- 未能添加SSL证书,错误1312
1.win+r打开运行,输入mmc 2.在控制台1[控制台根节点]->文件->添加/删除....->选择证书->添加-选择计算机账户->完成->确认 3.找到证书文 ...
- yum仓库及NFS共享
yum仓库及NFS共享 1.yum简介 yum是一个基于RPM包(是Red-Hat Package Manager红帽软件包管理器的缩写)构建的软件更新机制,能够自动解决软件包之间的依赖关系.解决了日 ...