题意:在一个n x m个格子组成的迷宫,'#'表示的格子不能走,'.'表示可以走。起点用'S'表示,目的地用'T'表示。只能向上下左右相邻的格子移动,每移动一次花费1秒。有q个单向传送阵,每个传送阵各有一个入口和一个出口,在入口处,你可以选择是否传送,传送过程会花费3秒;
注意:一个格子可能既有多个入口,又有多个出口。
请求出到达目的地的最短时间?
思路:用优先队列写bfs
代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n, m, q, dx[4]={1,-1,0,0}, dy[4]={0,0,1,-1};
char s[505][505];
vector<int> g[100005];//记录传送阵,用一个整数表示位置,整数=x*300+y;
struct state
{
int x, y;
}st,en;
struct w
{
int x, y, t;
}w, w1;
bool operator<(struct w a,struct w b)
{
return a.t>b.t;
};
int f[305][305];
int bfs()
{
memset(f,-1,sizeof(f));
priority_queue<struct w> que;
w.x=st.x;
w.y=st.y;
w.t=0;
que.push(w);
while(!que.empty())
{
w=que.top();
que.pop();
if(f[w.x][w.y]!=-1)
{
continue;
}
printf("%d %d %d\n",w.x,w.y,w.t);
f[w.x][w.y]=w.t;
if(w.x==en.x&&w.y==en.y)
{
return f[w.x][w.y];
}
for(int i=0;i<4;i++)
{
w1.x=w.x+dx[i];
w1.y=w.y+dy[i];
w1.t=w.t+1;
if(w1.x>=0&&w1.x<n&&w1.y>=0&&w1.y<m&&f[w1.x][w1.y]==-1&&s[w1.x][w1.y]!='#')
{
que.push(w1);
}
}
int v=w.x*300+w.y;
for(int i=0;i<g[v].size();i++)
{
w1.x=g[v][i]/300;
w1.y=g[v][i]%300;
w1.t=w.t+3;
if(w1.x>=0&&w1.x<n&&w1.y>=0&&w1.y<m&&f[w1.x][w1.y]==-1&&s[w1.x][w1.y]!='#')
{
que.push(w1);
}
}
}
return -1;
}
int main()
{
while(~scanf("%d%d%d",&n,&m,&q))
{
for(int i=0;i<n;i++)
{
scanf("%s",s[i]);
}
for(int i=0;i<q;i++)
{
int x, y, x2, y2;
scanf("%d%d%d%d",&x,&y,&x2,&y2);
g[x*300+y].push_back(x2*300+y2);
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(s[i][j]=='S')
{
st.x=i;
st.y=j;
}
if(s[i][j]=='T')
{
en.x=i;
en.y=j;
}
}
}
int z=bfs();
printf("%d\n",z);
for(int i=0;i<100005;i++)
{
g[i].clear();
}
}
return 0;
}

京公网安备 11010502036488号