深度优先搜索dfp学习

>>定义

  深度优先搜索属于图算法的一种,英文缩写为DFS即Depth First Search.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次.(according to Baidu)

>>几个例子

eg1

1215 迷宫 (求是否有路径)

http://ybt.ssoier.cn:8088/problem_show.php?pid=1215

复制代码
#include<bits/stdc++.h>
using namespace std;

int k,h;
char c[105][105];
bool ans=false;
int x[4]={1,0,-1,0};
int y[4]={0,-1,0,1};
int ax,ay,bx,by,nx,ny;
bool b[1005][1005];

void dfp(int x1,int y1){
    if(ans){
        return ;
    }
    
    for(int i=0; i<=3; i++){
        nx=x[i]+x1;
        ny=y[i]+y1;
        if(c[nx][ny]=='.' && nx>=0 && nx<h && ny>=0 && ny<h && b[nx][ny]==false){
            if(nx==bx && ny==by){
                ans=true;
            }
            b[nx][ny]=true;
            dfp(nx,ny);
            b[nx][ny]=false;
        }
    }
}
 
int main(){
    cin>>k;
    for(int i=0; i<k; i++){
        cin>>h;
        for(int j=0; j<h; j++){
            for(int z=0; z<h; z++){
                cin>>c[j][z];
            }
        }
        cin>>ax>>ay>>bx>>by;
        dfp(ax,ay);
        if(ans==false){
            cout<<"NO"<<endl;
        }else cout<<"YES"<<endl;
        ans=false;
        memset(b,0,sizeof(b));//要记得清空!!! 
    }
    return 0;
}
复制代码

 

eg2

1212LETTERS(求最长路径)

http://ybt.ssoier.cn:8088/problem_show.php?pid=1212

复制代码
#include<bits/stdc++.h>
using namespace std;

int maxs=0;
bool a[25][25],b[10005];
char c[25][25];
int R,S;
int x[4]={1,0,-1,0};
int y[4]={0,1,0,-1};

void dfs(int m,int n,int s){
    if(s>maxs){
        maxs=s;
    }
    for(int i=0; i<=3; i++){ 
        int nx=x[i]+m;
        int ny=y[i]+n;
        if(nx<=R && ny<=S && nx>=1 && ny>=1){
            if(b[c[nx][ny]]==false && a[nx][ny]==false){
                b[c[nx][ny]]=true;
                a[nx][ny]=true; 
                dfs(nx,ny,s+1);
                b[c[nx][ny]]=false;
                a[nx][ny]=false;
               }
            
        }
    }
}

int main(){
    cin>>R>>S;
    for(int i=1; i<=R; i++){
        for(int j=1; j<=S; j++){
            cin>>c[i][j];
        }
    }
    b[c[1][1]]=1;
    dfs(1,1,1);
    cout<<maxs<<endl;
    return 0;
}
复制代码

eg3

1213八皇后问题

http://ybt.ssoier.cn:8088/problem_show.php?pid=1213

复制代码
#include<bits/stdc++.h>
using namespace std;

int a[10][10],s=0;
bool b[1000], c[1000],d[1000];

void output(){
    cout<<"No. "<<s<<endl;//注意好是大写还是小写 
    for(int i=1; i<=8; i++){
        for(int j=1; j<=8; j++){
            cout<<a[j][i]<<" ";
        }
        cout<<endl;
    }
}

void dfs(int m){
    for(int j=1; j<=8; j++){
        if(b[j]==false && c[m+j-1]==false && d[m-j+8]==false){
            a[m][j]=1;
            b[j]=true;
            c[m+j-1]=true;
            d[m-j+8]=true;
            if(m==8){
                    s++;
                    output();
            }else {
                dfs(m+1);
            }
            b[j]=false;
            c[m+j-1]=false;
            d[m-j+8]=false;
            a[m][j]=0;//"=="和"="不要搞错啦!!! 
        }
    }
}



int main(){
    dfs(1); 
    return 0;
}
复制代码

>>Conclusion:1.不能走重复的路(用bool型判断+标记)(记得还原)

             2.上下左右走可以用int x,y的数组来达成

               3.每一次完成做需要做的标记(如比大小,统计次数等等)

 

 

复制代码
int x[4]={1,0,-1,0};
int y[4]={0,1,0,-1};
void dfs(int m,int n){//坐标(+方案数……) 
    if(达成需要的目标/比大小){
        做标记/赋值 
    }
    for(int i=0; i<=3; i++){ 
        int nx=x[i]+m;
        int ny=y[i]+n;//以上下左右为例,表示走的方向 
        if(nx<=R && ny<=S && nx>=1 && ny>=1)//保证不走出去
        {
            if(b[c[nx][ny]]==false && a[nx][ny]==false)//确保这条路未走过(不回头) 
            {
                b[c[nx][ny]]=true; 
                a[nx][ny]=true; //表示此条路已走过 
                dfs(nx,ny);//
                b[c[nx][ny]]=false;
                a[nx][ny]=false;//将路径还原 
            }
            
        }
    }
}
复制代码

 

 

 

 

posted @   竹余居居居居居  阅读(32)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示