DFS的根本:
把当前点标记成已访问
递归的访问和它相邻的点
寻找到的路径不能保证最短
注意bfs一定要设置成visited,否则当出现环的时候就死循环了
刚开始的时候我没有matrix[x][y]=2的环节
这样可能出现一个正方形全是0的死循环,这样dfs就绕在里面了。
应该把访问过的设置成2
#include <iostream>
using namespace std;
const int size = 105;
int matrix[size][size];
int from[size][size];
int m,n;
//1 左 2 上 3 右 4 下
void dfs(int x,int y,int direction){
if(matrix[x][y]==1) return ;
from[x][y]=direction;
if (matrix[x][y]==2) return;
else matrix[x][y]=2;
if(x==n&&y==n){
while(x!=1 || y!=1){
cout<<x<<","<<y<<endl;
if(from[x][y] == 1) y=y-1;
else if(from[x][y] == 2) x=x-1;
else if(from[x][y] == 3) y=y+1;
else if(from[x][y] == 4) x=x+1;
}
cout<<endl<<endl;
return ;
}
if(matrix[x][y-1]==0) dfs(x,y-1,3);
if(matrix[x][y+1]==0) dfs(x,y+1,1);
if(matrix[x-1][y]==0) dfs(x-1,y,4);
if(matrix[x+1][y]==0) dfs(x+1,y,2);
}
int main(int argc, char const *argv[])
{
while(cin>>m>>n){
for(int i=0;i<size;i++){
for(int j=0;j<size;j++)
matrix[i][j]=2;
}
memset(from,0,sizeof(from));
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++)
cin>>matrix[i][j];
}
dfs(1,1,0);
}
return 0;
}
其实这个from是必要的,只用matrix[x][y]==2的话,会导致
2 1 2 2 2
2 1 2 1 2
2 2 2 2 2
0 1 1 1 2
0 0 0 1 0
这样的岔口有很多个2
我这种from的方法,方向唯一。并且只有当成功的时候才会记录方向,其他时候不记录方向。
第二种dfs的方法,把dfs换成一个int函数直接用if(dfs)来判断是否成立。
int dfs2(int x,int y){
if(matrix[x][y]==1 || matrix[x][y]==2) return 0;
matrix[x][y]=2;
if(x==n&&y==n) return 1;
if(dfs2(x-1,y)) {cout<<x-1<<","<<y<<endl; return 1;}
if(dfs2(x,y+1)) {cout<<x<<","<<y+1<<endl; return 1;}
if(dfs2(x+1,y)) {cout<<x+1<<","<<y<<endl; return 1;}
if(dfs2(x,y-1)) {cout<<x<<","<<y-1<<endl; return 1;}
}
注意第二种dfs里面一定要return1
if成立代表后面的路已经能确定找到了,所以把这个位置输出,然后从上一个if的地方开始输出(上一个这条路上的位置)