深度优先搜索:简单讲就是搜到某条路尽头,再掉头回溯搜其他的路。此中重点是尽头的判断,和对走过的路进行标记。
一般采用递归的写法,模板大致如下:
DFS(node,visited):
if node is in visited:return
add node to visited;
主干操作;
for each neighbor in node.neighbors:
if neighbor is not in visited(能走是邻居且未访问过): DFS(neibor,visited)
回溯,把当前node影响消除,同时视情况将vis[当前node]修改为0
P1. 洛谷P1219八皇后为例
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
int n=0;
vector<int> ans;
int nums=0;
void showcurboard(bool** boa)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
cout<<boa[i][j];
cout<<endl;
}
}
void countans(vector<int> a)
{
for(int i=0;i<a.size();i++) cout<<a[i]<<" ";
cout<<endl;
}
bool inthemap(int a,int b)
{
return 1<=a&&a<=n&&1<=b&&b<=n;
}
void dealqueen(bool** boa,int a,int b,bool putortake)
{
for(int i=0;i<n+2;i++)
{
if(inthemap(a,i)) boa[a][i]=putortake;
if(inthemap(i,b)) boa[i][b]=putortake;
}
for(int i=-n;i<=n;i++)
{
if(inthemap(a+i,b+i)) boa[a+i][b+i]=putortake;
if(inthemap(a+i,b-i)) boa[a+i][b-i]=putortake;
}
}
void DFS(bool** &boa,int line,int column,bool** vis)//一定是node,visited
{
if(vis[line][column]==1) return;//主要是初始引入时判断,line==1时判断,其它节点下下面for那都判断过了
vis[line][column]=1;
ans.push_back(column);
dealqueen(boa,line,column,0);
if(line==n)
{
nums++;
if(nums<=3) countans(ans);
}
for(int j=1;j<=n;j++)
{
if(vis[line+1][j]==0&&boa[line+1][j]==1&&line+1<n+1) DFS(boa,line+1,j,vis);
}
vis[line][column]=0;//下四条都是回溯消除痕迹
dealqueen(boa,line,column,1);
ans.pop_back();
for(int i=0;i<ans.size();i++) dealqueen(boa,i+1,ans[i],0);
}
int main()
{
cin>>n;
bool** board=new bool*[n+2];
bool** visited=new bool*[n+2];
for(int i=0;i<n+2;i++)
{
board[i]=new bool[n+2];
visited[i]=new bool[n+2];
memset(board[i],1,sizeof(board[i]));
memset(visited[i],0,sizeof(visited[i]));
}
//showcurboard(board);
//dealqueen(board,2,3,0); //showcurboard(board);
for(int j=1;j<=n;j++)
DFS(board,1,j,visited);
cout<<nums;
return 0;
}