BZOJ3393 [Usaco2009 Jan]Laserphones 激光通讯 BFS
原文链接http://www.cnblogs.com/zhouzhendong/p/8371735.html
题目传送门 - BZOJ3393
题意概括
直接看原题的翻译吧,很容易懂的。

题解
我不知道这道题为什么放在网络流里面。
我也不知道网上为什么几乎都是SPFA。
这题就是一个裸的广搜啊啊啊。
20ms通过。
我们来考虑广搜。
只有改变方向是要花费的。
所以,我们入队的时候是一条线上的一起入队。
具体看我的pushnew函数。
然后主要的BFS循环内,只要扩展转弯就可以了(参见代码)。
我们考虑到,我这样做会导致在一个位置上进行多次转弯。
多次转弯,貌似是错的,但是由于本题特殊,这样一定是亏的,不会作为最优方案。
大概分成两种情况。
我们考虑如果只转了一次,显然是对的。
如果转了3次及以上,显然是亏的。
如果转了2次,只有可能:
1.原方向行进,显然是亏的。
2.原路返回,显然也是亏的。(自己脑补一下)
还有一个疑惑:比如下图的路线是否可能为最优路线(我的算法有可能会搜出这样的路线):

于是在(0,5)这个位置的镜子显然不对了。
但是这个显然不会是最优路线,直接挂掉。
代码
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;
const int WH=105,N=4*WH*WH;
int w,h,S,E,dis[N],vis[N],q[N],head,tail;
char g[WH][WH];
int dx[4]={-1, 0, 1, 0};
int dy[4]={ 0, 1, 0,-1};
char gc(){
char ch=getchar();
while (ch!='.'&&ch!='*'&&ch!='C')
ch=getchar();
return ch;
}
bool check(int x,int y){
return 1<=x&&x<=w&&1<=y&&y<=h&&g[x][y]!='*';
}
int HA(int dir,int x,int y){
return dir*w*h+(x-1)*h+y-1;
}
void HB(int v,int &dir,int &x,int &y){
dir=v/w/h,v%=w*h,x=v/h+1,y=v%h+1;
}
bool covered(int v1,int v2){
return v1%(w*h)==v2%(w*h);
}
void pushnew(int dir,int x,int y,int d){
while (check(x,y)){
int i=HA(dir,x,y);
if (vis[i])
break;
vis[i]=1,dis[i]=d;
q[++tail]=i;
x+=dx[dir],y+=dy[dir];
}
}
int main(){
scanf("%d%d",&h,&w);
for (int i=1;i<=w;i++)
for (int j=1;j<=h;j++)
g[i][j]=gc();
S=E=-1;
for (int i=1;i<=w;i++)
for (int j=1;j<=h;j++)
if (g[i][j]=='C')
if (!~S)
S=(i-1)*h+j-1;
else
E=(i-1)*h+j-1;
memset(vis,0,sizeof vis);
head=tail=0;
for (int i=0;i<4;i++)
dis[HA(i,E/h+1,E%h+1)]=w*h;
for (int i=0;i<4;i++)
pushnew(i,S/h+1,S%h+1,0);
while (head<tail){
int v=q[++head],dir,x,y;
if (covered(v,E))
break;
HB(v,dir,x,y);
pushnew((dir+1)%4,x,y,dis[v]+1);
pushnew((dir+3)%4,x,y,dis[v]+1);
}
int ans=w*h;
for (int i=0;i<4;i++)
ans=min(ans,dis[HA(i,E/h+1,E%h+1)]);
printf("%d",ans);
return 0;
}
BZOJ3393 [Usaco2009 Jan]Laserphones 激光通讯 BFS的更多相关文章
- bzoj3393 [Usaco2009 Jan]Laserphones 激光通讯
Description Input 第1行输入w和H,之后W行H列输入地图,图上符号意义如题目描述. Output 最少的对角镜数量. Sample Input 7 8 ....... ...... ...
- BZOJ3393:[USACO LPHONE] 激光通讯
分层图+堆优化的dijkstra 将原图分为4层,分别是只向上,向下,向左,向右建立边,然后层与层之间的转移很好处理.稠密图,应该用堆优化的dijkstra. //OJ 1845 //by Cydia ...
- BZOJ3396: [Usaco2009 Jan]Total flow 水流
3396: [Usaco2009 Jan]Total flow 水流 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 45 Solved: 27[Sub ...
- bzoj 1576: [Usaco2009 Jan]安全路经Travel 树链剖分
1576: [Usaco2009 Jan]安全路经Travel Time Limit: 10 Sec Memory Limit: 64 MB Submit: 665 Solved: 227[Sub ...
- BZOJ3394: [Usaco2009 Jan]Best Spot 最佳牧场
3394: [Usaco2009 Jan]Best Spot 最佳牧场 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 11 Solved: 9[Sub ...
- 1574: [Usaco2009 Jan]地震损坏Damage
1574: [Usaco2009 Jan]地震损坏Damage Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 425 Solved: 232[Subm ...
- 3396: [Usaco2009 Jan]Total flow 水流
3396: [Usaco2009 Jan]Total flow 水流 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 179 Solved: 73[Su ...
- 【BZOJ1576】[Usaco2009 Jan]安全路经Travel 最短路+并查集
[BZOJ1576][Usaco2009 Jan]安全路经Travel Description Input * 第一行: 两个空格分开的数, N和M * 第2..M+1行: 三个空格分开的数a_i, ...
- 【思维题 并查集 图论】bzoj1576: [Usaco2009 Jan]安全路经Travel
有趣的思考题 Description Input * 第一行: 两个空格分开的数, N和M * 第2..M+1行: 三个空格分开的数a_i, b_i,和t_i Output * 第1..N-1行: 第 ...
随机推荐
- ROM、PROM、EPROM、EEPROM、FLASH ROM简介
ROM指的是"只读存储器",即Read-Only Memory.这是一种线路最简单半导体电路,通过掩模工艺, 一次性制造,其中的代码与数据将永久保存(除非坏掉),不能进行修改.这玩 ...
- vue v-time指令封装(接口返回时间戳 在到日期转换)
// 全局时间戳转换指令注册Vue.directive('time',{ bind: function (el,binding) { let getTime = new Date(binding.va ...
- Codeforces 487E Tourists [广义圆方树,树链剖分,线段树]
洛谷 Codeforces 思路 首先要莫名其妙地想到圆方树. 建起圆方树后,令方点的权值是双联通分量中的最小值,那么\((u,v)\)的答案就是路径\((u,v)\)上的最小值. 然而这题还有修改, ...
- PID控制器开发笔记之七:微分先行PID控制器的实现
前面已经实现了各种的PID算法,然而在某些给定值频繁且大幅变化的场合,微分项常常会引起系统的振荡.为了适应这种给定值频繁变化的场合,人们设计了微分先行算法. 1.微分先行算法的思想 微分先行PID控制 ...
- Confluence 6 附件存储选项
在早期的 Confluence 版本中,我们允许存储附件到 WebDav 或者 Confluence 数据库中.针对新的 Confluence 安装,我们不再支持这 2 种存储了. 本地文件系统 在默 ...
- sublime c++
install: sudo add-apt-repository ppa:webupd8team/sublime-text-3 sudo apt-get update sudo apt-get i ...
- Memcached常用语法与java连接服务
memcached常用语法及java使用方式 Author:SimpleWu Memcached 存储命令 Memcached set 命令用于将 value(数据值) 存储在指定的 key(键) 中 ...
- 刷《剑指offer》笔记
本文是刷<剑指offer>代码中的学习笔记,学习ing.. 衡量时间和空间. 递归的代码较为简洁,但性能不如基于循环的实现方法.
- laravel 关联查询
- cf909C 线性dp+滚动数组好题!
一开始一直以为是区间dp.. /* f下面必须有一个s 其余的s可以和任意f进行匹配 所以用线性dp来做 先预处理一下: fffssfsfs==>3 0 1 1 dp[i][j] 表示第i行缩进 ...