bfs和dfs搜索总结

来源:互联网 发布:淘宝押金1000怎么上交 编辑:程序博客网 时间:2024/05/22 13:08

1.前言

bfs和dfs的题目写了10多道,大多借助解题报告写的,自己还是没有完全掌握。希望通过这次总结能对bfs和dfs的认识更清楚一些。bfs应该是一种层次搜索,它是通过借助队列实现的。bfs一般可以解决最优,最快情况的问题。bfs的缺点就是占用的空间太大。dfs应该是深度搜索,类似于树的先序搜索,它是通过递归来实现的。dfs可以解决有没有解的问题,能不能走出迷宫。

2.题型

(1)八连通块问题(HDOJ1214,POJ2386)

PS:刚开始痛心疾首的WA,

一定不要轻易定义全局变量

,尽量用的时候再定义,这道题开始我把i,j定义为全局变量,一直错误。。这个最起码调了4个小时。。。痛心疾首。
HDU 1241

#include<iostream>#include<cstdio>#include<algorithm>#include<queue>#include<string.h>using namespace std;#define maxn 110bool vis[maxn][maxn];char mp[maxn][maxn];int spx[]={0,1,0,-1,1,1,-1,-1};int spy[]={1,0,-1,0,-1,1,1,-1};int m,n;void dfs(int x,int y){        vis[x][y]=true;    for(int i=0;i<8;i++){        int nx=x+spx[i];        int ny=y+spy[i];        if(nx>=0 &&nx<m &&ny>=0 &&ny<n && mp[nx][ny]=='@' &&!vis[nx][ny]){            dfs(nx,ny);        }    }}int main(){    while(cin>>m>>n){        int i,j;        int cnt=0;        memset(vis,false,sizeof(vis));        if(m==0&&n==0) break;        for(i=0;i<m;i++){            scanf("%s",&mp[i]);        }        for(i=0;i<m;i++){            for(j=0;j<n;j++){                if(mp[i][j]=='@'&&!vis[i][j]){                    cnt++;                    dfs(i,j);                }            }        }        cout<<cnt<<endl;    }    return 0;}

(2)迷宫的最短路径BFS,并输出最短路径
http://blog.csdn.net/qq_37360631/article/details/76862479

/*POJ3984*/#include<iostream>#include<cstdio>#include<algorithm>#include<queue>#include<string.h>using namespace std;#define maxn 6#define N 5 //格子最多是5*5bool vis[maxn][maxn];int mp[maxn][maxn];int dir[4][2]={1,0,-1,0,0,1,0,-1};struct node{    int x,y,pre;}que[26];int sta=0,end=1; //数组模拟队列void print(int s){    if(que[s].pre!=-1){        print(que[s].pre);        cout<<"("<<que[s].x<<","<<que[s].y<<")"<<endl;    }}void bfs(int x,int y){    int k;    que[sta].pre=-1;    que[sta].x=x;    que[sta].y=y;    vis[x][y]=true;    while(sta<end){        for(k=0;k<4;k++){            int nx=que[sta].x+dir[k][0];            int ny=que[sta].y+dir[k][1];            if(nx>=0&&nx<N&&ny>=0&&ny<N&&mp[nx][ny]==0&&!vis[nx][ny]){                vis[nx][ny]=true;                que[end].pre=sta;                que[end].x=nx;                que[end].y=ny;                end++;            }            if(nx==N-1 && ny==N-1)                print(sta);        }        sta++;    }}

(3)迷宫的最少拐弯数BFS(HDOJ1728)
http://blog.csdn.net/qq_37360631/article/details/76999765

(4)回溯法解决数字组合的问题
HDOJ1342

/*字典序输出六个升序的组合*/#include<iostream>#include<cstdio>#include<algorithm>#include<queue>#include<string.h>using namespace std;int a[110],b[110],n;bool vis[110];void dfs(int num){    if(num==6){        for(int i=0;i<5;i++) cout<<b[i];        cout<<b[5]<<endl;        return ;    }    for(int i=0;i<n;i++){        if(!vis[i]&&a[i]>b[num-1]){            b[num]=a[i];            vis[i]=true;            dfs(num+1);            vis[i]=false;        }    }}int main(){    while(cin>>n){        memset(vis,false ,sizeof(vis));        int t;        if(t++) cout<<endl;        for(int i=0;i<n;i++){            scanf("%d",&a[i]);        }        dfs(0);    }    return 0;}

HDU1016

/*素数环问题*/#include<iostream>#include<cstdio>#include<algorithm>#include<queue>#include<string.h>#include<math.h>using namespace std;int a[110],b[110],n;bool vis[110],prime[51];//素数打表法,打表1-n之间的素数void init(){    int i,j;    for(i=2;i<=sqrt(50);i++){        if(prime[i]==0){  //全局变量自动初始化0            for(j=2;i*j<=50;j++){                prime[i*j]=1;            }        }    }    prime[1]=0;vis[1]=true; b[1]=1;}void print(){    for(int i=1;i<=n;i++)        if(i==1) cout<<b[i];        else cout<<" "<<b[i];    cout<<endl;}bool check(int depth){    if(depth==n+1) {    //先处理开头和最后一个数    if(prime[b[1]+b[depth-1]]==0         &&prime[b[depth-1]+b[depth-2]]==0) return true;    else return false;    }    //不是开头和最后一个数    else if(prime[b[depth-1]+b[depth-2]]==0) return true;    else return false;}void dfs(int depth){    if(false==check(depth)) return ;    if(depth==n+1){        print();        return ;    }    for(int i=2;i<=n;i++){        if(!vis[i]){            vis[i]=true;            b[depth]=i;            dfs(depth+1);            vis[i]=false;        }    }}int main(){    int t=1;    init();     while(scanf("%d",&n)!=EOF){        printf("Case %d:\n",t++);        if(1==n) cout<<"1"<<endl;        else                dfs(2);        cout<<endl;    }    return 0;}

HDOJ1015
DFS略

原创粉丝点击