Dfs depth-first and breadth-first search bfs summary + examples

DFS (Deep First Search) depth-first search

Depth-first traversal (DFS) algorithm is a connected graph to traverse. The idea is to start from a vertex, has been walking along a road in the end, if you can not reach the target solution concept, then return to the previous node, then the other way from the start to go in the end, the depth to go try to find that is a depth-first concept.

In short: do not hit the brick wall does not look back

Templates are as follows:

void dfs(int t)//t代表目前dfs的深度
{
    if(满足输出条件||走不下去了)
    {
        输出解;
        return;
    }
    else
    {
        for(int i=1;i<=尝试方法数;i++)
            if(满足进一步搜索条件)
            {
                为进一步搜索所需要的状态打上标记;
                dfs(t+1);
                恢复到打标记前的状态;//也就是说的{回溯一步}
            }
    }
}

Example a: Los Eight Queens Valley P1219

#include<bits/stdc++.h>
using namespace std;
int a[14],b[14],c[29],d[29];//分别存横、列、左对角线、右对角线访问标记
int n;
int cnt=0;
void print()
{
    cnt++;
    if(cnt<=3)
    {
        for(int i=1;i<=n;i++)
            cout<<a[i]<<" ";
        cout<<endl;
    }
}
void dfs(int k)
{
    int i=k;
    for(int j=1;j<=n;j++)
    {
        if(b[j]==0&&c[i+j]==0&&d[i-j+n]==0)//满足未被访问
        {
            a[i]=j;
            b[j]=1;c[i+j]=1;d[i-j+n]=1;//分别在竖排,左对角线,右对角线打上标记
            if(k<n)
                dfs(k+1);   //放置下一横排的皇后
            else if(k==n)
                print(); 
            b[j]=0;c[i+j]=0;d[i-j+n]=0;//回溯,标记重新置为0
        }           
    }
}
int main()
{
    cin>>n;
    dfs(1);
    cout<<cnt;
    return 0;
}

Two examples: cattle off network drizzle Matrix

#include<bits/stdc++.h>
using namespace std;
long long a[52][52];
int n;
set<int> s; //set集合中数据唯一且有序

void dfs(int x,int y,int sum){
    if(x==n && y==n){
        s.insert(sum);  //走到(n,n)则把sum插入集合s
        return;
    }
    if(x+1<=n){
        dfs(x+1,y,sum+a[x+1][y]);//向下走
    }
    if(y+1<=n){
        dfs(x,y+1,sum+a[x][y+1]);//向右走
    }
}
int main() {
    cin>>n;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            cin>>a[i][j];   //录入矩阵
        }
    }
    dfs(1,1,a[1][1]);   //开始深搜
    cout<<s.size()<<endl;//输出集合s的大小
    return 0;
}

BFS (Breath First Search) BFS

BFS different than depth-first search in that the depth-first search that no matter how many forks in the road, first a way to go in the end, unsuccessful returns on an intersection and then select the next fork in the road, and breadth-first search that faced when an intersection, all the fork are down, and then select an entry, then it shunts the case record, and then returns to a fork into another, and such operations are repeated.

In short: a blanket search or like water ripples as loosed

Templates are as follows:

//通常用队列queue实现,或者有些时候用数组模拟队列
void bfs()
{
    初始化队列q
    q.push(起点);
    标记上起点;
    while(!q.empty())
    {
        取队首元素u;
         q.pop();//队首元素出队
         for(int i=0;i<可以走的方向数;i++)
         {
             if(下一步满足边界内,未访问等条件)
             {
                 q.push();//该点入队
                 标记上该点;
                 ...
             }
         }
    }
}

Example a: Luo Gu P1443 horse traversal

This question requires the horse to go a few steps to reach at least a point from a certain point, it can only be used bfs

#include<bits/stdc++.h>
using namespace std;
int h[8]={-2,-1,1,2,-2,-1,1,2},z[8]={1,2,2,1,-1,-2,-2,-1};//8个方向 
int vis[410][410];
int cnt[410][410];//记录到达每个坐标点的步数 
queue<pair<int,int> >q;
int n,m;
void bfs()
{
    while(!q.empty())
    {
        int x=q.front().first;
        int y=q.front().second;
        q.pop();
        for(int i=0;i<8;i++)
        {
            int xx=x+h[i];
            int yy=y+z[i];
            if(xx>n||xx<1||yy>m||yy<1||vis[xx][yy]==1)continue;//到达边界或已经访问则跳过此次循环
            q.push(make_pair(xx,yy));
            vis[xx][yy]=1;
            cnt[xx][yy]=cnt[x][y]+1;
        }
    }
}
int main()
{
    memset(cnt,-1,sizeof(cnt));
    int x,y;
    cin>>n>>m>>x>>y;
    vis[x][y]=1;
    cnt[x][y]=0;
    q.push(make_pair(x,y));
    bfs();
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            printf("%-5d",cnt[i][j]);//控制格式
        }
        cout<<endl;
    }
    return 0;
}

Example two: Luo Gu P1162 color Tiantu

The key to this problem is through extensive search of the periphery 1 0 marked mark

#include<bits/stdc++.h>
using namespace std;
int h[4]={-1,0,1,0},z[4]={0,-1,0,1};
int n,a[35][35]; 
queue<pair<int,int> >q;
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            cin>>a[i][j];
    for(int i=0;i<=n+1;i++)//在四周加0,避免在角落的0搜不过去
    {
        a[0][i]=0;
        a[n+1][i]=0;
        a[i][0]=0;
        a[n+1][i]=0;
    }
    q.push(make_pair(0,0));
    while(!q.empty())
    {
        int x=q.front().first;
        int y=q.front().second;
        q.pop();
        for(int i=0;i<4;i++)
        {
            int x2=x+h[i];
            int y2=y+z[i];
            if(x2>=0&&y2>=0&&x2<=n+1&&y2<=n+1&&a[x2][y2]==0)
            {
                a[x2][y2]=-1;//1外围的0标志为-1
                q.push(make_pair(x2,y2));   
            }
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(a[i][j]==-1)cout<<"0 ";
            else if(a[i][j]==1)cout<<"1 ";
            else if(a[i][j]==0)cout<<"2 ";
        }
        cout<<endl;
    }
    return 0;   
} 

To sum up, in fact, a lot of questions dfs and bfs can be the solution, but on the shortest (excellent) path problem only with breadth-first bfs

Guess you like

Origin www.cnblogs.com/jiyi-conding/p/11402680.html