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;
}

发布了40 篇原创文章 · 获赞 18 · 访问量 7567

猜你喜欢

转载自blog.csdn.net/zmx2473162621/article/details/104039922
今日推荐