题意描述

[USACO09JAN]Laserphones S

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

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

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

算法分析

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

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

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

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

代码实现

  1. #include<cstdio>
  2. #include<iostream>
  3. #include<algorithm>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<queue>
  7. #define N 510
  8. #define INF 0x3f3f3f3f
  9. using namespace std;
  10. int n,m,sx,sy,ex,ey,dis[N*N<<2],head[N*N<<2],cnt=0;
  11. int dx[5]={0,1,-1,0,0};
  12. int dy[5]={0,0,0,1,-1};
  13. bool vis[N*N<<2];
  14. char a[N][N];
  15. struct Edge{
  16. int nxt,to,val;
  17. }ed[N*N<<3];
  18. int read(){
  19. int x=0,f=1;char c=getchar();
  20. while(c<'0' || c>'9') f=(c=='-')?-1:1,c=getchar();
  21. while(c>='0' && c<='9') x=x*10+c-48,c=getchar();
  22. return x*f;
  23. }
  24. void init(){
  25. m=read(),n=read();
  26. char c;
  27. for(int i=1;i<=n;i++)
  28. for(int j=1;j<=m;j++){
  29. cin>>c;
  30. if(c=='C'){
  31. if(!sx) sx=i,sy=j;
  32. else ex=i,ey=j;
  33. }
  34. a[i][j]=c;
  35. }
  36. return;
  37. }
  38. int ID(int t,int x,int y){return (t-1)*n*m+(x-1)*m+y;}
  39. void add(int u,int v,int w){
  40. ed[++cnt].nxt=head[u];
  41. ed[cnt].to=v;
  42. ed[cnt].val=w;
  43. head[u]=cnt;
  44. return;
  45. }
  46. void build(){
  47. for(int t=1;t<=4;t++)
  48. for(int i=1;i<=n;i++)
  49. for(int j=1;j<=m;j++){
  50. int fx=i+dx[t];
  51. int fy=j+dy[t];
  52. if(fx<1 || fx>n || fy<1 || fy>m || a[fx][fy]=='*' || a[i][j]=='*') continue;
  53. add(ID(t,i,j),ID(t,fx,fy),0);
  54. }
  55. for(int i=1;i<=n;i++)
  56. for(int j=1;j<=m;j++){
  57. if(a[i][j]=='*') continue;
  58. for(int u=1;u<=4;u++)
  59. for(int v=1;v<=4;v++)
  60. if(u^v) add(ID(u,i,j),ID(v,i,j),1);
  61. }
  62. return;
  63. }
  64. int ans=INF;
  65. priority_queue<pair<int,int> >q;
  66. void dij(int s){
  67. while(!q.empty()) q.pop();
  68. memset(dis,0x3f,sizeof(dis));
  69. memset(vis,false,sizeof(vis));
  70. dis[s]=0;q.push(make_pair(0,s));
  71. while(!q.empty()){
  72. int u=q.top().second;q.pop();
  73. if(vis[u]) continue;
  74. vis[u]=true;
  75. for(int i=head[u];i;i=ed[i].nxt){
  76. int v=ed[i].to,w=ed[i].val;
  77. if(dis[v]>dis[u]+w){
  78. dis[v]=dis[u]+w;
  79. q.push(make_pair(-dis[v],v));
  80. }
  81. }
  82. }
  83. return;
  84. }
  85. void work(){
  86. for(int i=1;i<=4;i++){
  87. dij(ID(i,sx,sy));
  88. for(int j=1;j<=4;j++)
  89. ans=min(ans,dis[ID(j,ex,ey)]);
  90. }
  91. return;
  92. }
  93. int main(){
  94. init();
  95. build();
  96. work();
  97. printf("%d\n",ans);
  98. return 0;
  99. }

完结撒花

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. 怎样优雅的实现INotifyPropertyChanged

    第一 安装nuget包 PropertyChanged.Fody. 第二 在类的上方加上 [PropertyChanged.AddINotifyPropertyChangedInterface] 类似 ...

  2. 软件定义网络实验记录④--Open vSwitch 实验——Mininet 中使用 OVS 命令

    一.实验目的 Mininet 安装之后,会连带安装 Open vSwitch,可以直接通过 Python 脚本调用 Open vSwitch 命令,从而直接控制 Open vSwitch,通过实验了解 ...

  3. 上部:问道 | R语言数据分析(北京邮电大学)自整理笔记

    第1章 气象万千 数以等观 数据分析:发现数据背后的规律 等号的重要性,建立模型 第2章所谓学习.归类而已 2.1所谓学习,归类而已(1) ps:机器学习只是归归类? 有监督学习--分类:无监督学习- ...

  4. jwtUtils顾名思意

    1 package com.pipihao.blog.util; 2 import java.util.Date; 3 4 import javax.crypto.SecretKey; 5 impor ...

  5. 037 01 Android 零基础入门 01 Java基础语法 04 Java流程控制之选择结构 04 switch结构

    037 01 Android 零基础入门 01 Java基础语法 04 Java流程控制之选择结构 04 switch结构 本文知识点:Java中的switch结构 选择结构分类 选择结构只有如下2种 ...

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

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

  7. 轻轻松松学CSS:Grid布局

    网页布局总的来说经历了以下四个阶段: 1.古老的table表格布局,现在基本已被淘汰. 2.float浮动布局(或者position定位布局),借助float.position 等属性等进行布局,这种 ...

  8. git 查看本地分支和切换本地分支的命令

    查看本地分支,和当前所在的分支 git branch -vv git checkout developer 切换到developer分支

  9. MeteoInfoLab脚本示例:图形版面、点标注

    在MeteoInfoLab界面中,图形的大小会随着它所在的窗口的大小改变而改变,在需要精确控制图中一些要素的位置的时候会比较困难,这时可以用figure函数的一些参数来控制图形版面大小.figure函 ...

  10. day05 Pyhton学习

    1字典 字符串"" 列表[,] 元祖(,) 字典{:,} 集合{,} 2.增加 dic={} dic['name'] = '周润发' dic.setdefault() 如果dict ...