/*
最短路的变形问题 特别判断旋转门就可以了
*/
#include<cstdio>
#include<cstring>#include<queue>
#include<vector>
#define INF 1<<30
using namespace std;
int n,m,vis[110][110],ms,ld,d[10010],mad[110][110];
char map[110][110];
int dx[]= {1,-1,0,0}; // s n e w
int dy[]= {0,0,1,-1};
int dp[110*110];
struct Node
{
int x,y;
int step;
bool operator < (const Node &s) const
{
return step>s.step;
}
};
int insert(Node next,int i)
{
if(next.x>=0&&next.x<n&&next.y>=0&&next.y<m)
{
if(map[next.x][next.y]=='.')
return 1;
else if(map[next.x][next.y]!='#')
{
if(map[next.x][next.y]=='N'&&i==0)
return 1;
else if(map[next.x][next.y]=='S'&&i==1)
return 1;
else if(map[next.x][next.y]=='W'&&i==2)
return 1;
else if(map[next.x][next.y]=='E'&&i==3)
return 1;
}
}
return 0;
}
int bfs()
{
memset(vis,0,sizeof(vis));
for(int i = 0; i <= n*m; i++)
dp[i] = INF;
dp[(n-1)*m] = 0;
priority_queue<Node>q;
while(!q.empty()) q.pop();
q.push((Node)
{
n-1,0,0
});
ms = INF;
int tp;
while(!q.empty())
{
Node tm = q.top();
q.pop();
int te = tm.x*m+tm.y;
if(vis[tm.x][tm.y]) continue;
vis[tm.x][tm.y]=1;
//printf("%d.%d\n",tm.x,tm.y);
if(tm.x==0&&tm.y==m-1)
{
if(ms > tm.step)
ms = tm.step;
}
if(map[tm.x][tm.y]=='#')
continue;
else if(map[tm.x][tm.y]=='.')
for(int i = 0; i < 4; i++)
{
Node next;
next.x = tm.x+dx[i];
next.y = tm.y+dy[i];
tp = next.x*m+next.y;
//printf("%d %d.\n",dp[te],dp[tp]);
if(insert(next,i))
if(dp[tp]>dp[te]+1)
{
dp[tp]=dp[te]+1;
next.step = dp[tp];
q.push(next);
}
}
else
{
int td = mad[tm.x][tm.y];
if(map[tm.x][tm.y]=='N')
{
Node next;
// S
next.x=tm.x+dx[0];
next.y=tm.y+dy[0];
tp = next.x*m+next.y;
if(insert(next,0))
if(dp[tp]>dp[te]+2*td+1)
{
dp[tp]=dp[te]+2*td+1;
next.step=dp[tp];
q.push(next);
}
// W
next.x=tm.x+dx[3];
next.y=tm.y+dy[3];
tp = next.x*m+next.y;
if(insert(next,3))
if(dp[tp]>dp[te]+td+1)
{
dp[tp]=dp[te]+td+1;
next.step=dp[tp];
q.push(next);
}
// E
next.x=tm.x+dx[2];
next.y=tm.y+dy[2];
tp = next.x*m+next.y;
if(insert(next,2))
if(dp[tp]>dp[te]+td+1)
{
dp[tp]=dp[te]+td+1;
next.step=dp[tp];
q.push(next);
}
}
else if(map[tm.x][tm.y]=='S')
{
Node next;
//int td = mad[tm.x][tm.y];
// N
next.x=tm.x+dx[1];
next.y=tm.y+dy[1];
tp = next.x*m+next.y;
if(insert(next,1))
if(dp[tp]>dp[te]+2*td+1)
{
dp[tp]=dp[te]+2*td+1;
next.step=dp[tp];
q.push(next);
}
// W
next.x=tm.x+dx[3];
next.y=tm.y+dy[3];
tp = next.x*m+next.y;
if(insert(next,3))
if(dp[tp]>dp[te]+td+1)
{
dp[tp]=dp[te]+td+1;
next.step=dp[tp];
q.push(next);
}
// E
next.x=tm.x+dx[2];
next.y=tm.y+dy[2];
tp = next.x*m+next.y;
if(insert(next,2))
if(dp[tp]>dp[te]+td+1)
{
dp[tp]=dp[te]+td+1;
next.step=dp[tp];
q.push(next);
}
}
else if(map[tm.x][tm.y]=='W')
{
Node next;
//int td = mad[tm.x][tm.y];
// E
next.x=tm.x+dx[2];
next.y=tm.y+dy[2];
tp = next.x*m+next.y;
if(insert(next,2))
if(dp[tp]>dp[te]+2*td+1)
{
dp[tp]=dp[te]+2*td+1;
next.step=dp[tp];
q.push(next);
}
// N
next.x=tm.x+dx[1];
next.y=tm.y+dy[1];
tp = next.x*m+next.y;
if(insert(next,1))
if(dp[tp]>dp[te]+td+1)
{
dp[tp]=dp[te]+td+1;
next.step=dp[tp];
q.push(next);
}
// S
next.x=tm.x+dx[0];
next.y=tm.y+dy[0];
tp = next.x*m+next.y;
if(insert(next,0))
if(dp[tp]>dp[te]+td+1)
{
dp[tp]=dp[te]+td+1;
next.step=dp[tp];
q.push(next);
}
}
else if(map[tm.x][tm.y]=='E')
{
Node next;
//int td = mad[tm.x][tm.y];
// W
next.x=tm.x+dx[3];
next.y=tm.y+dy[3];
tp = next.x*m+next.y;
if(insert(next,3))
if(dp[tp]>dp[te]+2*td+1)
{
dp[tp]=dp[te]+2*td+1;
next.step=dp[tp];
q.push(next);
}
// N
next.x=tm.x+dx[1];
next.y=tm.y+dy[1];
tp = next.x*m+next.y;
if(insert(next,1))
if(dp[tp]>dp[te]+td+1)
{
dp[tp]=dp[te]+td+1;
next.step=dp[tp];
q.push(next);
}
// S
next.x=tm.x+dx[0];
next.y=tm.y+dy[0];
tp = next.x*m+next.y;
if(insert(next,0))
if(dp[tp]>dp[te]+td+1)
{
dp[tp]=dp[te]+td+1;
next.step=dp[tp];
q.push(next);
}
}
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
ld=0;
memset(mad,0,sizeof(mad));
scanf("%d%d",&n,&m);
for(int i = 0; i < n; i++)
{
scanf("%s",map[i]);
for(int j = 0; j < m; j++)
if(map[i][j]!='.'&&map[i][j]!='#')
ld++;
}
for(int i = 0; i < ld; i++)
scanf("%d",&d[i]);
int lm=0;
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
if(map[i][j]!='.'&&map[i][j]!='#')
{
mad[i][j] = d[lm++];
}
bfs();
if(ms>=(1<<30))
puts("Poor Kianoosh");
else
printf("%d\n",ms);
}
return 0;
}

本文介绍了一种基于最短路径算法的变形问题实现方案,针对包含旋转门的地图环境,通过自定义的数据结构和广度优先搜索算法来寻找从起点到终点的最短路径。文章详细解释了如何处理不同类型的旋转门以及它们对路径选择的影响。
75

被折叠的 条评论
为什么被折叠?



