ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

dfs

2021-11-21 16:01:56  阅读:191  来源: 互联网

标签:int void dfs 访问 邻居 节点


这里记录一下老师上课讲过的dfs.

主要思路是,我们对于每一个节点都设置白色、灰色和黑色三种颜色,分别表示三种状态:未访问、正在访问和访问完毕。这三种状态的标准是根据某一个具体节点的邻居节点来定的,就是说,对于某一个具体节点,如果还没有访问完该节点的所有邻居节点,那么就表示这个节点处于正在访问状态,如果所有邻居节点都访问完毕,那就表示这个节点已经访问完毕。

那么首先,为了简单起见,我们直接用一个二维数组来表示边,且在初始化的时候,所有节点到其他任何节点之间的距离都设置为无穷大,包括节点到它自己之间的距离。

1 void init()
2 {
3     for (int i = 1; i <= n; ++i) {
4         for (int j = 1; j <= n; ++j) {
5             edge[i][j] = INT_MAX;
6         }
7     }
8 }

然后,就可以开始dfs了。这个函数的参数只需要设置一个,表示当前正在访问的节点。首先,我们当然就是需要把这个节点的颜色设置为灰色啦!然后,我们开始访问它的所有邻居节点,一旦发现一个邻居节点并且这个邻居节点的颜色状态也是白色(表示未访问),那么就以这个邻居节点为基准,继续dfs.这就体现了深度的特点。等到全部访问完后,也就是这个节点的所有邻居节点都访问完毕了,那么就可以把这个节点的颜色设置为黑色了,最后就把它打印出来就可以了。

 1 void dfs(int u)
 2 {
 3     color[u] = "grey";
 4     for (int j = 1; j <= n; ++j) {
 5         if (edge[u][j] != INT_MAX && color[j] == "white") {
 6             dfs(j);
 7         }
 8     }
 9     color[u] = "black";
10     cout << u << " ";
11 }

最后,为了防止访问的这个图是一个森林,我们还要来一个函数,遍历一遍这个图的所有节点,一旦发现有节点是白色的,那就访问。

void GraphTravel()
{
    for (int i = 1; i <= n; ++i) {
        if (color[i] == "white") {
            dfs(i);
        }
    }
}

最后来一波完整代码:

#include <iostream>
#include <algorithm>
#include <queue>
#define N 100
using namespace std;
queue<int> q;
int edge[N][N];
string color[N];
int n, edges;
void init()
{
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n; ++j) {
            edge[i][j] = INT_MAX;
        }
    }
}

void dfs(int u)
{
    color[u] = "grey";
    for (int j = 1; j <= n; ++j) {
        if (edge[u][j] != INT_MAX && color[j] == "white") {
            dfs(j);
        }
    }
    color[u] = "black";
    cout << u << " ";
}

void GraphTravel()
{
    for (int i = 1; i <= n; ++i) {
        if (color[i] == "white") {
            dfs(i);
        }
    }
}

int main()
{
    int start, end, weight;
    cout << "输入点的数量:" << endl;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        color[i] = "white";
    }
    cout << "输入边的数量:" << endl;
    cin >> edges;
    cout << "依次输入起点、终点和边的权值:" << endl;
    init();
    for (int i = 1; i <= edges; ++i) {
        cin >> start >> end >> weight;
        edge[start][end] = weight;
        edge[end][start] = weight;
    }
    GraphTravel();
    return 0;
}

再来一波运行效果:

 

 对了,这个图长这样:

 

 可能读者会对最后打印出来节点的顺序有所疑问,其实这是节点“变黑的顺序”,这个顺序很有用!具体有啥用呢?To be continued...

 

标签:int,void,dfs,访问,邻居,节点
来源: https://www.cnblogs.com/EvanTheGreat/p/15584764.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有