题解:CF173B Chamber of Secrets

题目分析

题意

题干很丑陋

于是自己转换了一下问题:

可以考虑成倒着跑,从 (1,1) 出发,方向向右,抵达 (n,m+1)

每次遇到 # 可以以 1 的代价更换方向。其余情况均只能以原方向前进。

求最小代价。

分析

考虑分层图最短路。

  • 每一层只能沿一个方向移动,边权为 0

  • # 处向别的层连边,边权为 1,表示切换方向代价为 1

貌似一般的最短路算法被卡了。

我们容易发现该图中边权为 01,考虑使用一些奇怪的技巧。

使用 01 BFS。顺带省去了建边的步骤。

时间复杂度 O(n)

Code

#include<bits/stdc++.h>
using namespace std;
#define maxn 1003
int dis[maxn][maxn][4];
string mp[maxn];
struct st
{
int x, y, d;
st(int X, int Y, int D):x(X), y(Y), d(D) {}
};
deque<st> q;
int dx[]={1, -1, 0, 0};
int dy[]={0, 0, 1, -1};
#define chk(i, j) ((i)&&(j)&&(i<=n)&&(j<=m))
#define mp(i, j) mp[i][j-1]
/*
^
1
<3 2>
0
v
*/
void bfs(int n, int m)
{
memset(dis, 0x3f, sizeof dis);
q.emplace_back(1, 1, 2);
dis[1][1][2]=0;
while(!q.empty())
{
auto [x, y, p]=q.front();
q.pop_front();
if(!(dis[x+dx[p]][y+dy[p]][p]<=dis[x][y][p]||!chk(x+dx[p], y+dy[p])))
{
dis[x+dx[p]][y+dy[p]][p]=dis[x][y][p];
q.emplace_front(x+dx[p], y+dy[p], p);
}
if(mp(x, y)=='#')
for(int i=0;i<=3;i++)
{
if(i==p) continue;
if(dis[x+dx[i]][y+dy[i]][i]<=dis[x][y][p]+1||!chk(x+dx[i], y+dy[i])) continue;
dis[x+dx[i]][y+dy[i]][i]=dis[x][y][p]+1;
q.emplace_back(x+dx[i], y+dy[i], i);
}
}
}
int main()
{
int n, m;
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>mp[i];
bfs(n, m+1);
cout<<(dis[n][m+1][2]==0x3f3f3f3f?-1:dis[n][m+1][2]);
}

本文作者:Jimmy-LEEE

本文链接:https://www.cnblogs.com/redacted-area/p/18379530

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Jimmy-LEEE  阅读(6)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起