深搜回溯與不回溯的區別

一、需要不斷嘗試以達到最終目的時需要回溯,比如數獨、全排列。

以下爲全排列代碼:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
string str;
string temp;
vector<bool> vis;
void dfs(int cnt,int n)
{
    if(cnt==n)
    {
        cout<<temp<<endl;
        return;
    }
    for(int i=0;i<n;i++)
    {
        if(vis[i]==false)
        {
            temp.push_back(str[i]);
            vis[i]=true;
            dfs(cnt+1,n);
            vis[i]=false;
            temp.pop_back();
        }
    }
}
int main()
{
    getline(cin,str);
    sort(str.begin(),str.end());
    int n=str.size();
    vis.resize(n);
    dfs(0,n);
    return 0;
}

搜完了回來了需要重置vis狀態。

二、一錘子買賣時不需要回溯,比如圖的深度優先遍歷、二叉樹節點間的最大距離問題。

#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
struct node
{
    int up;
    int left;
    int right;
};
node tree[500001];
bool vis[500001];
int n;
int root;
int maxcnt=-1;
int stroot=0;
void dfs(int root,int cnt)
{
    vis[root]=true;
    if(cnt>maxcnt)
    {
        stroot=root;
        maxcnt=cnt;
    }
    //printf("root=%d cnt=%d maxcnt=%d\n",root,cnt,maxcnt);
    if(root==0)
    {
        return;
    }
    if(vis[tree[root].up]==false)
    {
        dfs(tree[root].up,cnt+1);
    }
    if(vis[tree[root].left]==false)
    {
        dfs(tree[root].left,cnt+1);
    }
    if(vis[tree[root].right]==false)
    {
        dfs(tree[root].right,cnt+1);
    }
}
int main()
{
    scanf("%d%d",&n,&root);
    int i;
    for(i=1;i<=n;i++)
    {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        tree[a].left=b;
        tree[a].right=c;
        tree[b].up=a;
        tree[c].up=a;
    }
    memset(vis,0,sizeof(vis));
    dfs(root,0);
    memset(vis,0,sizeof(vis));
    dfs(stroot,0);
    printf("%d\n",maxcnt+1);
    return 0;
}

歡迎大家關注/訂閱我的微信公衆號Code Art Online,我會在我的公衆號分享個人見聞,發現生活趣味;這裏不僅有0和1,還有是詩和遠方↓↓↓

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章