题意描述

[USACO09JAN]Laserphones S

学过物理的同学都知道这种镜子是可以把光线旋转 90 度的。

那么显然就是要求添加镜子的最小个数。

貌似题目漏了一句就是题目保证有解的情况。

算法分析

其实可以联想到之前的分层图最短路。(不要问我为什么)

建立4层相同的图。层内只能向着某个方向走,因此在可以走的地方建权值为0的边。

层间实现转弯,两两建权值为1的边,表示可以转弯,但有花费。

最后从每一层的起点到每一层的终点跑最短路,统计花费就行了。

代码实现

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#define N 510
#define INF 0x3f3f3f3f
using namespace std; int n,m,sx,sy,ex,ey,dis[N*N<<2],head[N*N<<2],cnt=0;
int dx[5]={0,1,-1,0,0};
int dy[5]={0,0,0,1,-1};
bool vis[N*N<<2];
char a[N][N];
struct Edge{
int nxt,to,val;
}ed[N*N<<3]; int read(){
int x=0,f=1;char c=getchar();
while(c<'0' || c>'9') f=(c=='-')?-1:1,c=getchar();
while(c>='0' && c<='9') x=x*10+c-48,c=getchar();
return x*f;
} void init(){
m=read(),n=read();
char c;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
cin>>c;
if(c=='C'){
if(!sx) sx=i,sy=j;
else ex=i,ey=j;
}
a[i][j]=c;
}
return;
} int ID(int t,int x,int y){return (t-1)*n*m+(x-1)*m+y;} void add(int u,int v,int w){
ed[++cnt].nxt=head[u];
ed[cnt].to=v;
ed[cnt].val=w;
head[u]=cnt;
return;
} void build(){
for(int t=1;t<=4;t++)
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
int fx=i+dx[t];
int fy=j+dy[t];
if(fx<1 || fx>n || fy<1 || fy>m || a[fx][fy]=='*' || a[i][j]=='*') continue;
add(ID(t,i,j),ID(t,fx,fy),0);
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
if(a[i][j]=='*') continue;
for(int u=1;u<=4;u++)
for(int v=1;v<=4;v++)
if(u^v) add(ID(u,i,j),ID(v,i,j),1);
}
return;
} int ans=INF;
priority_queue<pair<int,int> >q; void dij(int s){
while(!q.empty()) q.pop();
memset(dis,0x3f,sizeof(dis));
memset(vis,false,sizeof(vis));
dis[s]=0;q.push(make_pair(0,s));
while(!q.empty()){
int u=q.top().second;q.pop();
if(vis[u]) continue;
vis[u]=true;
for(int i=head[u];i;i=ed[i].nxt){
int v=ed[i].to,w=ed[i].val;
if(dis[v]>dis[u]+w){
dis[v]=dis[u]+w;
q.push(make_pair(-dis[v],v));
}
}
}
return;
} void work(){
for(int i=1;i<=4;i++){
dij(ID(i,sx,sy));
for(int j=1;j<=4;j++)
ans=min(ans,dis[ID(j,ex,ey)]);
}
return;
} int main(){
init();
build();
work();
printf("%d\n",ans);
return 0;
}

完结撒花

P2937 [USACO09JAN]Laserphones S的更多相关文章

  1. 洛谷 题解 P2937 【[USACO09JAN]激光电话Laserphones】

    看到这题,一下就想到了爆搜.(不过这题输入也是够坑的) 单纯的搜索肯定是会超时的,所以这里需要考虑一些剪枝. 我们令bin[i][j][k]为在第i行j列时,方向为k的最小镜子数,若当时的镜子数已大于 ...

  2. luogu P2934 [USACO09JAN]安全出行Safe Travel

    题目链接 luogu P2934 [USACO09JAN]安全出行Safe Travel 题解 对于不在最短路树上的边(x, y) 1 | | t / \ / \ x-----y 考虑这样一种形态的图 ...

  3. 2018.07.06 洛谷P2936 [USACO09JAN]全流Total Flow(最大流)

    P2936 [USACO09JAN]全流Total Flow 题目描述 Farmer John always wants his cows to have enough water and thus ...

  4. P2934 [USACO09JAN]安全出行Safe Travel

    P2934 [USACO09JAN]安全出行Safe Travel https://www.luogu.org/problemnew/show/P2934 分析: 建出最短路树,然后考虑一条非树边u, ...

  5. 洛谷——P2935 [USACO09JAN]最好的地方Best Spot

    P2935 [USACO09JAN]最好的地方Best Spot 题目描述 Bessie, always wishing to optimize her life, has realized that ...

  6. $P2935 [USACO09JAN]最好的地方Best Spot$

    P2935 [USACO09JAN]最好的地方Best Spot Floyd的水题(黄题) 海星. 这可能是我第一道发的Floyd的博客 inline void Floyd(){ ;k<=n;k ...

  7. 洛谷 P2932 [USACO09JAN]地震造成的破坏Earthquake Damage

    P2932 [USACO09JAN]地震造成的破坏Earthquake Damage 题目描述 Wisconsin has had an earthquake that has struck Farm ...

  8. bzoj3393 [Usaco2009 Jan]Laserphones 激光通讯

    Description Input 第1行输入w和H,之后W行H列输入地图,图上符号意义如题目描述. Output 最少的对角镜数量. Sample Input 7 8 ....... ...... ...

  9. ●洛谷P2934 [USACO09JAN]安全出行Safe Travel

    题链: https://www.luogu.org/problemnew/show/P2934 题解: 最短路(树),可并堆(左偏堆),并查集. 个人感觉很好的一个题. 由于题目已经明确说明:从1点到 ...

随机推荐

  1. Python-临时文件文件模块-tempfile

    案例: 某项目中,从传感器中获得采集数据,每收集到1G的数据后做是数据分析,最终只保留数据分析的结果,收集到的数据放在内存中,将会消耗大量内存,我们希望把这些数据放到一个临时的文件中 临时文件不能命名 ...

  2. 日志分析平台ELK之前端展示kibana

    之前的博客一直在聊ELK集群中的存储.日志收集相关的组件的配置,但通常我们给用户使用不应该是一个黑黑的shell界面,通过接口去查询搜索:今天我们来了ELK中的前端可视化组件kibana:kibana ...

  3. 剑指Offer(三):从尾到头打印链表

    一.前言 刷题平台:牛客网 二.题目 输入一个链表,返回一个反序的链表. 1.思路 通常,这种情况下,我们不希望修改原链表的结构.返回一个反序的链表,这就是经典的"后进先出",我们 ...

  4. 一道web入门题

    9月27日00:00 这道题是我将hctf_warmup魔改之后得到的,难度比较低,主要还是讲一些web相关的思考方式,所以这篇文章会比较冗长过于详细.(毕竟是给小姑娘入门看的23333).就当M1s ...

  5. XML流操作

    /// <summary>         /// 保存XML为指定格式         /// </summary>         /// <param name=& ...

  6. 扫描仪扫描文件处理-Photoshop批处理内存不足问题解决

    一次批处理上千张扫描图片,如果提示内存不足,这时候需要修改操作系统虚拟内存.最小值:512(512M),最大值建议51200(50G). 同时设置让Photoshop使用100%. 

  7. firstBlog

    第一篇博客 markdown语法的学习 基本语法 标题与段落 在文字前面加1-6个#号来表示来代表一级标题到六级标题 一级标题 五级标题 列表 对于无序列表,可以使用字符-,+和*作为列表的标记 - ...

  8. spring boot:用rocketmq发送延时消息用来取消订单(spring boot 2.3.3)

    一,为什么要用延时消息来取消订单? 1,为什么要取消订单 在电商的下单过程中,需要在生成订单时扣减库存, 但有可能发生这种情况:用户下了单,临时改变主意不再支付, 则订单不能无限期的保留,因为还要把占 ...

  9. spring boot:使用多个线程池实现实现任务的线程池隔离(spring boot 2.3.2)

    一,为什么要使用多个线程池? 使用多个线程池,把相同的任务放到同一个线程池中,可以起到隔离的作用,避免有线程出错时影响到其他线程池,例如只有一个线程池时,有两种任务,下单,处理图片,如果线程池被处理图 ...

  10. Python之for循环和列表

    for循环: 有限循环 基本语法: for 变量 in 可迭代对象: 循环体 也可使用break,continue,for else list列表初识: 列表可放任意数据类型:[int,str,boo ...