跳转至

图上搜索

DFS

对于一个无权图,你可以通过类似以下的方法深度优先遍历整个图:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int n;
vector <int> g[N];
bool visited[N];
void dfs (int u) {
    visited[u] = true;
    for (auto v : g[u]) {
        if (! visited[v]) {
            dfs (v);
        }
    }
}
void traverse_the_graph () {
    // clear flag
    fill (visited + 1, visited + n + 1, false);
    // enumerated possible start
    // subject to change if there are extra requirements:
    // e.g., if every point is reachable by 1, dfs(1) is sufficient
    for (int i = 1; i <= n; i++) {
        if (! visited[i]) {
            dfs (i);
        }
    }
}

本地运行一个稍大的图就 Segment Fault 了,如何解决?

请参考 开栈

BFS

对于一个无权图,你可以通过类似以下的方法广度优先遍历整个图:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
void bfs (int start) {
    // clear flag
    fill (visited + 1, visited + n + 1, false);
    queue <int> q;
    q.push(start);
    visited[start] = true;
    while (! q.empty()) {
        int u = q.front();
        q.pop();
        for (auto v : g[u]) {
            if (! visited[v]) {
                visited[v] = true;
                q.push(v);
            }
        }
    }
}

DFS 序与 BFS 序

如果你关心 DFS 或者 BFS 中顺序的信息,你可以额外记录下来。

比如,如果你关心 DFS 序,那你可以在访问到一个顶点的时候记录 order[step ++] = u;。我们以 Kosaraju 算法中需要用到的 Finishing Time 为例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
int order[N], step = 1;
void dfs (int u) {
    visited[u] = true;
    for (auto v : g[u]) {
        if (! visited[v]) {
            dfs (v);
        }
    }
    order[step ++] = u;
}
void traverse_the_graph () {
    fill (visited + 1, visited + n + 1, false);
    for (int i = 1; i <= n; i++) {
        if (! visited[i]) {
            dfs (i);
        }
    }
    // order[1...n] now contains the finishing time
}

如果你关心 BFS 序,一种简便方法是使用数组手写队列替换掉 queue <int>,这样在 BFS 结束后数组内就是 BFS 序。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
int q[N], head, tail;
void bfs () {
    head = 1, tail = 0;
    q[++ tail] = start;
    while (head <= tail) {
        int u = q[head ++];
        for (auto v : g[u]) {
            if (! visited[v]) {
                visited[v] = true;
                q[++ tail] = v;
            }
        }
    }
    // q[1...tail] now contains the bfs order
}