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. 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. 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?Problem Statement
Square $(i, j)$ is occupied by an obstacle if $S_{i,j}=$ #
, and is empty if $S_{i,j}=$ .
.
Multiple surveillance cameras may be placed at the same square.Constraints
.
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);
}
标签:square,int,obstacle,surveillance,Camera,监控,Security,left
From: https://www.cnblogs.com/mekoszc/p/16907390.html