DFS(啊哈!算法)
DFS:一条路走到黑
1.全排列问题:
#include<iostream> using namespace std; int a[1000],book[1000]; int n; void dfs(int step){ if(step==n+1){ for(int i=1;i<=n;i++){ if(i!=n){ cout<< a[i]<<' '; }else{ cout<<a[i]<<endl; } } return; } for(int i=1;i<=n;i++){ if(book[i]==0){ a[step]=i; book[i]=1; dfs(step+1); book[i]=0; } } return; } int main(){ cin>>n; dfs(1); return 0; }
DFS问题解决的关键是当下该如何做,至于下一步的做法和当下做法是一样的.
Model:
void dfs(int step){
判断边界
尝试每一种可能 for(int i=1;i<=n;i++){
尝试下一步dfs(step+1)
}
返回
}
每一次尝试就是一种扩展,每一个盒子都有n种扩展法但是并不是每一种扩展法都能扩展成功
2.abc+cde=fgh
#include<iostream> using namespace std; int a[100],book[100]; int count; void dfs(int step){ if(step==10){ if(a[1]*100+a[2]*10+a[3]+a[4]*100+a[5]*10+a[6]==a[7]*100+a[8]*10+a[9]){ count++; cout<<a[1]<<a[2]<<a[3]<<'+'<<a[4]<<a[5]<<a[6]<<'='<<a[7]<<a[8]<<a[9]<<endl; } return; } for(int i=1;i<=9;i++){ if(book[i] ==0){ a[step]=i; book[i]=1; dfs(step+1); book[i]=0; } } return; } int main(){ dfs(1); cout<<count/2; return 0; }
3.迷宫问题
#include<iostream> using namespace std; char map[100][100]; bool vis[100][100]; int n,m; int p,q; int minnum=9999; int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}}; void dfs(int x,int y,int step){ if(x==p && y==q){ if(step<minnum){ minnum=step; return; } return; } for(int i=0;i<4;i++){ int tx=x+dir[i][0]; int ty=y+dir[i][1]; if(tx>=0 && tx<n && ty>=0 && ty<m && map[tx][ty] !='#' && !vis[tx][ty]){ vis[tx][ty]=1; dfs(tx,ty,step+1); vis[x][y]=0; } } return; } int main(){ cin>>n>>m; int startx,starty; cin>>startx>>starty; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cin>>map[i][j]; } } for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ if(map[i][j] == 'Q'){ p=i; q=j; } } } vis[startx][starty]=1; dfs(startx,starty,0); vis[startx][starty]=0; cout<<minnum<<endl; return 0; }
4.dfs染色法
#include<iostream> using namespace std; int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}}; int map[51][51]; int book[51][51]; int sx=6,sy=8; int sum; void dfs(int x,int y,int color){ map[x][y]=color; for(int i=0;i<4;i++){ int tx=x+dir[i][0]; int ty=y+dir[i][1]; if(tx>=1 && tx<=10&&ty>=1 && ty<=10 && map[tx][ty]>0 && !book[tx][ty]){ book[tx][ty]=1; sum++; dfs(tx,ty,color); book[tx][ty]=0; } } return; } int main(){ for(int i=1;i<=10;i++){ for(int j=1;j<=10;j++){ cin>>map[i][j]; } } cout<<endl; book[sx][sy]=1; sum=1; dfs(sx,sy,-1); for(int i=1;i<=10;i++){ for(int j=1;j<=10;j++){ if(j!=10){ cout<<map[i][j]<<' '; }else{ cout<<map[i][j]<<endl; } } } return 0; }
5.dfs求图中独立子图
在4的基础上对每个非0点dfs即可
#include<iostream> using namespace std; int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}}; int map[51][51]; int book[51][51]; int sx=6,sy=8; int sum; int numcol=-1; void dfs(int x,int y,int color){ map[x][y]=color; for(int i=0;i<4;i++){ int tx=x+dir[i][0]; int ty=y+dir[i][1]; if(tx>=1 && tx<=10&&ty>=1 && ty<=10 && map[tx][ty]>0 && !book[tx][ty]){ book[tx][ty]=1; sum++; dfs(tx,ty,color); book[tx][ty]=0; } } return; } int main(){ for(int i=1;i<=10;i++){ for(int j=1;j<=10;j++){ cin>>map[i][j]; } } cout<<endl; for(int i=1;i<=10;i++){ for(int j=1;j<=10;j++){ if(map[i][j] > 0){ sum=1; book[i][j]=1; dfs(i,j,numcol); numcol--; } } } for(int i=1;i<=10;i++){ for(int j=1;j<=10;j++){ if(j!=10){ cout<<map[i][j]<<' '; }else{ cout<<map[i][j]<<endl; } } } return 0; }