其他分享
首页 > 其他分享> > dfs

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