迷宮最短路徑(C++)
阿新 • • 發佈:2021-01-13
迷宮最短路問題
接上次經典迷宮問題
問題:這次迷宮問題不僅要求判斷是否能夠找到通路,並且要求找到最短能到達迷宮所需的步數,即最短路徑問題
暴力演算法:對每個結點進行遍歷,記錄每種路徑的步數;
優化剪枝:當遍歷步數大於ans之前第一次找到ans初始化值為無窮大,當第一次找到通路路徑後,ans被第一次step替換。之後的每次路徑只要比前一次step小,就會被step小的替代;
剪枝:而在尋找通路的過程中,只要步數大於了前一次所找通路的step,這次尋找終止,返回下一次尋找;
程式碼如下:
#include <stdio.h>
#include <iostream>
using namespace std;
char Map[50][50];
int n,m,p,q,vis[50][50],ans,flag;
const int N=1000;
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};//上下左右走位
void dfs(int x,int y,int step)//經典DFS模板
{
if(step>ans)//剪枝
return;
if(Map[x][y]=='T')//走到終點
{
flag=1;
if(ans>step)
ans=step;
return;
}
for(int i=0;i< 4;i++)
{
int tx=x+dir[i][0];
int ty=y+dir[i][1];
if(tx>=0&&tx<=m&&ty>=0&&ty<=n&&vis[tx][ty]==0&&Map[tx][ty]!='*')//下一步未出界且下一步位置未被訪問過(DFS演算法的vis[][])
{
vis[tx][ty]=1;
dfs(tx,ty,step+1);
vis[tx][ty]=0;
}
}
}
int main()
{
cin>> n;
while(n--)
{
flag=0;
cin>>m>>n;
memset(vis,0,sizeof(vis));
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
cin>>Map[i][j];
if(Map[i][j]=='S')
{
int p=i;
int q=j;
// printf("%d\n%d",p,q);
}
}
}
ans=9999999;
dfs(p,q,0);
if(flag==1) cout<<ans<<endl;
else cout<<-1<<endl;
}
return 0;
}