杂物间终于开始好好学算法了11:DFSBFS树和图的深度/广度优先遍历

Posted 杂物间的无聊生活

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了杂物间终于开始好好学算法了11:DFSBFS树和图的深度/广度优先遍历相关的知识,希望对你有一定的参考价值。

前言(于2021/04/30)

GRE告一段落,时间多了起来,于是我决定每天分一些时间出来好好学习算法,补一下之前在acwing买的课(wtf?

并且只贴代码(C++),懒得写那些讲解了,网上都有,当然,代码网上也都有,但这跟我只贴代码有什么关系?

05/27:

懒的搞题面了,从现在开始这个系列仅作为我在凭着兴趣坚持学习竞赛类算法的证明hh


DFS

排列数字

#include <iostream>

using namespace std;

const int N = 10;

int n;
int path[N];
bool st[N];

void dfs(int u)
{
    if (u == n)
    {
        for (int i = 0; i < n; i ++) printf("%d ", path[i]);
        puts("");
        return;
    }

    for (int i = 1; i <= n; i ++)
    {
        if (!st[i])
        {
            path[u] = i;
            st[i] = true;
            dfs(u + 1);
            st[i] = false;
        }
    }
}

int main()
{
    cin >> n;

    dfs(0);

    return 0;
}

作者:DrPirate2931
链接:https://www.acwing.com/activity/content/code/content/1332573/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

n-皇后问题

#include <iostream>

using namespace std;

const int N = 20;

int n;
char g[N][N];
bool col[N], dg[N], udg[N];

void dfs(int u)
{
    if (u == n)
    {
        for (int i = 0; i < n; i ++) puts(g[i]);
        puts("");
        return ;
    }

    for (int i = 0; i < n; i ++)
    {
        if (!col[i] && !dg[u + i] && !udg[n - u + i])
        {
            g[u][i] = 'Q';
            col[i] = dg[u + i] = udg[n - u + i] = true;
            dfs(u + 1);
            col[i] = dg[u + i] = udg[n - u + i] = false;
            g[u][i] = '.';
        }
    }
}

int main()
{
    cin >> n;
    for (int i = 0; i < n; i ++)
    {
        for (int j = 0; j < n; j ++)
        {
            g[i][j] = '.';
        }
    }

    dfs(0);

    return 0;
}

作者:DrPirate2931
链接:https://www.acwing.com/activity/content/code/content/1332687/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

BFS

走迷宫

#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

typedef pair<intint> PII;

const int N = 110;

int n, m;
int g[N][N];
int d[N][N];
PII q[N * N];

int bfs()
{
    int hh = 0, tt = 0;
    q[0] = {00};

    memset(d, -1sizeof d);
    d[0][0] = 0;

    int dx[4] = {-1010}, dy[4] = {010-1};

    while (hh <= tt)
    {
        auto t = q[hh ++];

        for (int i = 0; i < 4; i ++)
        {
            int x = t.first + dx[i], y = t.second + dy[i];
            if (x >= 0 && x < n && y < m && y >= 0 && g[x][y] == 0 && d[x][y] == -1)
            {
                d[x][y] = d[t.first][t.second] + 1;
                q[++ tt] = {x, y};
            }
        }
    }

    return d[n - 1][m - 1];
}

int main()
{
    cin >> n >> m;

    for (int i = 0; i < n; i ++)
    {
        for (int j = 0; j < m; j ++)
        {
            cin >> g[i][j];
        }
    }

    cout << bfs() << endl;

    return 0;
}

作者:DrPirate2931
链接:https://www.acwing.com/activity/content/code/content/1338897/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

八数码

#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <queue>

using namespace std;

int bfs(string start)
{
    queue<string> q;
    unordered_map<stringint> d;

    q.push(start);
    d[start] = 0;

    int dx[4] = {-1010}, dy[4] = {010-1};

    string end = "12345678x";
    while (q.size())
    {
        auto t = q.front();
        q.pop();

        if (t == end) return d[t];

        int distance = d[t];
        int k = t.find('x');
        int x = k / 3, y = k % 3;
        for (int i = 0; i < 4; i ++)
        {
            int a = x + dx[i], b = y + dy[i];
            if (a >= 0 && a < 3 && b >= 0 && b < 3)
            {
                swap(t[a * 3 + b], t[k]);
                if (!d.count(t))
                {
                    d[t] = distance + 1;
                    q.push(t);
                }
                swap(t[a * 3 + b], t[k]);
            }
        }
    }

    return -1;
}

int main()
{
    char s[2];

    string start;
    for (int i = 0; i < 9; i ++)
    {
        cin >> s;
        start += s;
    }

    cout << bfs(start) << endl;

    return 0;
}

作者:DrPirate2931
链接:https://www.acwing.com/activity/content/code/content/1339197/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

树与图的深度优先遍历

树的重心

#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010, M = N * 2;

int n;
int h[N], e[M], ne[M], idx;
bool st[N];

int ans = N;

void add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}

int dfs(int u)
{
    st[u] = true;

    int sum = 1, res = 0;
    for (int i = h[u]; i != -1; i = ne[i])
    {
        int j = e[i];
        if (!st[j])
        {
            int s = dfs(j);
            res = max(s, res);
            sum += s;
        }
    }

    res = max(res, n - sum);

    ans = min(ans, res);

    return sum;
}

int main()
{
    cin >> n;
    memset(h, -1sizeof h);

    for (int i = 0; i < n - 1; i ++)
    {
        int a, b;
        cin >> a >> b;
        add(a, b), add(b, a);
    }

    dfs(1);

    cout << ans << endl;

    return 0;
}

作者:DrPirate2931
链接:https://www.acwing.com/activity/content/code/content/1342139/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

树与图的广度优先遍历

图中点的层次

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 100010;

int n, m;
int h[N], e[N], ne[N], idx;
int d[N], q[N];

void add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}

int bfs()
{
    int hh = 0, tt = 0;
    q[0] = 1;

    memset(d, -1sizeof d);

    d[1] = 0;

    while (hh <= tt)
    {
        int t = q[hh ++];

        for (int i = h[t]; i != -1; i = ne[i])
        {
            int j = e[i];
            if (d[j] == -1)
            {
                d[j] = d[t] + 1;
                q[++ tt] = j;
            }
        }
    }

    return d[n];
}

int main()
{
    cin >> n >> m;
    memset(h, -1sizeof h);

    for (int i = 0; i < m; i ++)
    {
        int a, b;
        cin >> a >> b;
        add(a, b);
    }

    cout << bfs() << endl;

    return 0;
}

作者:DrPirate2931
链接:https://www.acwing.com/activity/content/code/content/1342209/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


以上是关于杂物间终于开始好好学算法了11:DFSBFS树和图的深度/广度优先遍历的主要内容,如果未能解决你的问题,请参考以下文章

4.算法通关面试 --- 树和图

dfsbfs的终于弄明白了

力扣_中级算法_树和图_4~6题_和_回溯算法_第1题

算法学习笔记 二叉树和图遍历—深搜 DFS 与广搜 BFS

树和图的区别

树和图的区别