两种方法思路:将门设置为不可通过,然后计算从起点到终点的直接路径;计算起点到钥匙+钥匙到门+门到终点的路径之和,比较他们两个哪一个更小,如果比较结果等于0x3f3f3f3f的话,说明终点被墙围住了,不可能到达。

两个计算模拟了尝试直接到达终点,以及拿钥匙再到终点的这两个过程。如果门挡住去路,那么最短路一定是拿钥匙再到终点的路径,如果门不能挡住去路,那么最短路是两者最小值。如果钥匙拿不到并且门也挡住了去路,那么显然是死局。

两种方法,第一种是dijksra算法求最短路

#include<bits/stdc++.h>
using namespace std;
int h,w;
const int M=505;
char mp[M][M];
bool vis[M][M];
int sx,sy,ex,ey,dx,dy,kx,ky;
bool flag;
struct node{
	int x,y;
	node(int a,int b){x=a; y=b;}
	node(){}
};
int mov[4][2]={{1,0},{-1,0},{0,1},{0,-1}};

bool check(int x,int y){
	return x>=1&&x<=h&&y>=1&&y<=w;
}
int key;
int dis[M][M];
int bfs(int px,int py,int tx,int ty){
	memset(dis,0x3f3f3f3f,sizeof(dis));
	memset(vis,0,sizeof(vis));
    queue<node> q;
	vis[px][py]=true;
	q.push(node(px,py));
	dis[px][py]=0;
	while(!q.empty()){
		node tmp=q.front();
		q.pop();
		for(int i=0;i<4;i++){
			int xx=tmp.x+mov[i][0];
			int yy=tmp.y+mov[i][1];
			if(xx==tx&&yy==ty)	return dis[tmp.x][tmp.y]+1;
			if(check(xx,yy)&&!vis[xx][yy]&&mp[xx][yy]!='W'&&mp[xx][yy]!='D'){
				if(dis[xx][yy]>=dis[tmp.x][tmp.y]+1){
					dis[xx][yy]=dis[tmp.x][tmp.y]+1;
				//	cout<<dis[xx][yy]<<"  ";
					vis[xx][yy]=true;
					q.push(node(xx,yy));
				}
				
			}
		}
	}
	return 0x3f3f3f3f;
}

int main(){
	cin>>h>>w;
	for(int i=1;i<=h;i++)
		for(int j=1;j<=w;j++){
			cin>>mp[i][j];
			if(mp[i][j]=='S'){
				sx=i; sy=j;
			}
			if(mp[i][j]=='E'){
				 ex=i; ey=j;
			}
			if(mp[i][j]=='D'){
				dx=i; dy=j;
			}
			if(mp[i][j]=='K'){
				kx=i; ky=j;
			}
		}
	int dis1=bfs(sx,sy,ex,ey); 
	int dis2=bfs(sx,sy,kx,ky);
	if(dis2!=0x3f3f3f3f){
		dis1=min(dis1,dis2+bfs(kx,ky,dx,dy)+bfs(dx,dy,ex,ey));
	}
	if(dis1==0x3f3f3f3f)	cout<<"-1"<<'\n';
	else cout<<dis1<<'\n';
	int ans=0;
	
}

第二种是根据bfs先到达终点的路径一定最短的原理

#include<bits/stdc++.h>
using namespace std;
int h,w;
const int M=505;
char mp[M][M];
bool vis[M][M];
int sx,sy,ex,ey,dx,dy,kx,ky;
bool flag;
struct node{
	int x,y,step;
	node(int a,int b,int c){x=a; y=b;step=c;}
	node(){}
};
int mov[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
queue<node> q;
bool check(int x,int y){
	return x>=1&&x<=h&&y>=1&&y<=w;
}
int key;

int bfs(int px,int py,int tx,int ty){
	memset(vis,0,sizeof(vis));
	
	while(!q.empty()){
		q.pop();
	}
	vis[px][py]=true;
	q.push(node(px,py,0));
	dis[px][py]=0;
	while(!q.empty()){
		node tmp=q.front();
		q.pop();
		for(int i=0;i<4;i++){
			int xx=tmp.x+mov[i][0];
			int yy=tmp.y+mov[i][1];
			if(xx==tx&&yy==ty)	{
			//	cout<<tmp.step+1<<"  ";
			//	cout<<endl;
				
				return tmp.step+1;
			}
			if(check(xx,yy)&&!vis[xx][yy]&&mp[xx][yy]!='W'&&mp[xx][yy]!='D'){
				
				
				vis[xx][yy]=true;
				q.push(node(xx,yy,tmp.step+1));
			
				
			}
		}
	}
//	cout<<endl;
	return 0x3f3f3f3f;
}

int main(){
	cin>>h>>w;
	for(int i=1;i<=h;i++)
		for(int j=1;j<=w;j++){
			cin>>mp[i][j];
			if(mp[i][j]=='S'){
				sx=i; sy=j;
			}
			if(mp[i][j]=='E'){
				 ex=i; ey=j;
			}
			if(mp[i][j]=='D'){
				dx=i; dy=j;
			}
			if(mp[i][j]=='K'){
				kx=i; ky=j;
			}
		}
	int dis1=bfs(sx,sy,ex,ey); 
	int dis2=bfs(sx,sy,kx,ky);
	if(dis2!=0x3f3f3f3f){
		dis1=min(dis1,dis2+bfs(kx,ky,dx,dy)+bfs(dx,dy,ex,ey));
	}
	if(dis1==0x3f3f3f3f)	cout<<"-1"<<'\n';
	else cout<<dis1<<'\n';
	int ans=0;
	
}