相信第一个最短路问题应该几乎都是没什么问题的。。直接跑BFS就可以了,第二个。我感觉和这里的题目有点像 POJ 1724 同样都是在约束条件下的最短路,因此解决这些问题的方法应该也是类似的,我先阐述这个问题吧,那个问题我以后在写一篇博客,然后这两个相互链接,扯远了。链接补上:有约束的最短路
第二种路径的要求就是不能沿着同样的方向再走一次,我们知道普通的最短路上是没有环的,也就是每个格子只到达一次,那么,我们可以类比过来,在这种约束条件下,到达一个格子上的此时的方向也只能有一次,意思就是你第一次到达A格的时候方向是向下,你走了许多步之后,假若你还到了A格,那么此时你的方向一定不会是向下,否则你走的这条路一定不是最短路。然后用一个500×500×5的数组来标记上下左右的状态就好,然后实现的时候注意一下,不要把墙壁的点也加进去了。,,我的实现方法是把墙壁的权值理解为无穷大。。在第一次写的时候依然把墙壁加进去了。。。其实多做了及其多的无穷的搜索,这个还是吃了苦头的。
Tips:利用一个优先队列来储存状态,距离越短的权值越高,所以在这种情况下,一旦取出的第一个点是终点,那么便可以退出循环,因为此时一定是最短路径。另外一定就是在push的时候需要满足约束条件。
(代码可能会有点长呀,,下次尝试用数组来代替方向,然后写一个判断函数好了。)
#include
#include
#include
using namespace std;
char str[5];
int n,m,r1,c1,r2,c2,board[505][505],len1[505][505],times=1,ans=0x3f3f3f3f;
bool flag[505][505],vis[505][505][5];
struct Node{
int x,y,dir,dis;
Node(int a=0,int b=0,int c=0,int d=0){x=a,y=b,dir=c,dis=d;}
bool operator<(const Node& a)const{return dis>a.dis;};
}te;
queue q;
priority_queue qw;
int main(){
while(scanf("%d%d%d%d%d%d",&n,&m,&r1,&c1,&r2,&c2)!=EOF){
for(int i=0;i=0&&len1[te.x][te.y-1]>len1[te.x][te.y]+board[te.x][te.y-1]){
len1[te.x][te.y-1]=len1[te.x][te.y]+board[te.x][te.y-1];
if(!flag[te.x][te.y-1])
flag[te.x][te.y-1]=true,q.push(Node(te.x,te.y-1));
}
if(te.y+1len1[te.x][te.y]+board[te.x][te.y+1]){
len1[te.x][te.y+1]=len1[te.x][te.y]+board[te.x][te.y+1];
if(!flag[te.x][te.y+1])
flag[te.x][te.y+1]=true,q.push(Node(te.x,te.y+1));
}
if(te.x-1>=0&&len1[te.x-1][te.y]>len1[te.x][te.y]+board[te.x-1][te.y]){
len1[te.x-1][te.y]=len1[te.x][te.y]+board[te.x-1][te.y];
if(!flag[te.x-1][te.y])
flag[te.x-1][te.y]=true,q.push(Node(te.x-1,te.y));
}
if(te.x+1len1[te.x][te.y]+board[te.x+1][te.y]){
len1[te.x+1][te.y]=len1[te.x][te.y]+board[te.x+1][te.y];
if(!flag[te.x+1][te.y])
flag[te.x+1][te.y]=true,q.push(Node(te.x+1,te.y));
}
}
qw.push(Node(r1-1,c1-1,0,board[r1-1][c1-1]));
for(int i=1;i<=4;++i)
vis[r1-1][c1-1][i]=true;
while(!qw.empty()){
te=qw.top();qw.pop();
if(te.x==r2-1&&te.y==c2-1){
ans=te.dis;
break;
}
if(te.dir!=1&&te.y-1>=0){
if(!vis[te.x][te.y-1][1]&&board[te.x][te.y-1]!=0x3f3f3f3f)
qw.push(Node(te.x,te.y-1,1,te.dis+board[te.x][te.y-1])),vis[te.x][te.y-1][1]=true;
}
if(te.dir!=2&&te.y+1=0){
if(!vis[te.x-1][te.y][3]&&board[te.x-1][te.y]!=0x3f3f3f3f)
qw.push(Node(te.x-1,te.y,3,te.dis+board[te.x-1][te.y])),vis[te.x-1][te.y][3]=true;
}
if(te.dir!=4&&te.x+1=0x3f3f3f3f)?-1:ans);ans=0x3f3f3f3f;
for(int i=0;i