ACM模板 DFS深搜以及其應用

描述

深度優先搜索算法(英語:Depth-First-Search,DFS)是一種用於遍歷或搜索樹或圖的算法。沿着樹的深度遍歷樹的節點,儘可能深的搜索樹的分支。當節點v的所在邊都己被探尋過,搜索將回溯到發現節點v的那條邊的起始節點。這一過程一直進行到已發現從源節點可達的所有節點爲止。如果還存在未被發現的節點,則選擇其中一個作爲源節點並重復以上過程,整個進程反覆進行直到所有節點都被訪問爲止。屬於盲目搜索。 深度優先搜索是圖論中的經典算法,利用深度優先搜索算法可以產生目標圖的相應拓撲排序表,利用拓撲排序表可以方便的解決很多相關的圖論問題,如最大路徑問題等等。 因發明“深度優先搜索算法”,約翰·霍普克洛夫特與羅伯特·塔揚在1986年共同獲得計算機領域的最高獎:圖靈獎。源於:維基百科

應用

迷宮問題

問題描述:有一個m*n的迷宮(m行n列),用1表示可以走,而0表示不可以走;第一行是兩個數m,n,接下來的是m行n列由1,0組成的數據,最後兩行是起始點和終點;
輸出:所有可行的路徑,描述一個點時用(x,y)的形式,每個點之間用“->”表示方向;如果無法到達終點則輸出-1;

解決代碼:

#include <bits/stdc++.h>
using namespace std;
const int maxm = 50, maxn = 50;
int m, n;                                 //m行n列
int vis[maxm][maxn];                      //訪問數組,代表是否訪問過
int f[4][2] = {0, -1, -1, 0, 0, 1, 1, 0}; //指示方向
int map0[maxm][maxn];                     //地圖
vector<pair<int, int>> q;                 //vector容器,pair對
int xb, yb, xe, ye;                       //b代表起始點,e代表終點
bool flag = true;                         //標誌

bool judge(int x, int y) //判斷函數,判斷x,y是否符合條件
{
    return (x >= 1 && x <= m && y >= 1 && y <= n && vis[x][y] == 0 && map0[x][y] == 1);
}

void DFS(int x, int y)
{
    if (x == xe && y == ye) //判斷結束的標誌
    {
        flag = false;
        for (int i = 0; i < q.size(); i++)
        {
            if (i == 0)
                cout << "(" << q[i].first << "," << q[i].second << ")";
            else
            {
                cout << "->"
                     << "(" << q[i].first << "," << q[i].second << ")";
            }
        }
        cout << endl;
        return;
    }
    //開始深搜,四個方向
    for (int i = 0; i < 4; i++)
    {
        int x1 = x + f[i][0];
        int y1 = y + f[i][1];
        if (judge(x1, y1)) //表明本次方向的目的座標符合條件
        {
            vis[x1][y1] = 1;          //標記已用
            pair<int, int> z(x1, y1); //pair數組對
            q.push_back(z);           //把z加入到q中
            DFS(x1, y1);              //遞歸
            vis[x1][y1] = 0;          //回溯
            q.pop_back();             //彈出
        }
    }
}
int main()
{
    memset(map0, 0, sizeof map0);
    memset(vis, 0, sizeof vis);
    cin >> m >> n;
    for (int i = 1; i <= m; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            cin >> map0[i][j];
        }
    }
    cin >> xb >> yb >> xe >> ye;
    vis[xb][yb] = 1;
    pair<int, int> z(xb, yb);
    q.push_back(z);
    DFS(xb, yb);
    if (flag)
    {
        cout << -1 << endl;
    }
    return 0;
}

全排列問題

問題描述:對於一個數n,輸出從1,…,n的全排列組合;
解決代碼:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 50;
int n;
int vis[maxn];//訪問數組
vector<int> q;//可變數組

//傳進來的是當前點
void DFS(int x)
{
    if (x == n) //結束標誌
    {
        for (int i = 0; i < q.size(); i++)
        {
            if (i == 0)
                cout << q[i];
            else
                cout << "    " << q[i];
        }
        cout << endl;
        return;
    }

    for (int i = 1; i <= n; i++) 
    {
        if (vis[i] == 0)
        {
            vis[i] = 1;
            q.push_back(i);
            DFS(x + 1);
            vis[i] = 0;
            q.pop_back();
        }
    }
}
int main()
{
    memset(vis, 0, sizeof vis);//初始化數組
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        q.push_back(i);
        vis[i] = 1;
        DFS(1);
        vis[i] = 0;//回溯
        q.clear();
    }
    //DFS(0);
    return 0;
}

創作不易,點個贊支持一下唄!
在這裏插入圖片描述

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