Skip to content

Depth First Search

Basic DFS

bool is_ancestor(int anc, int des)
{
    return tin[anc] < tin[des] && tout[anc] > tout[des];
}

void dfs_util(int v)
{
    color[v] = GREY;
    tin[v] = timer++;
    for ( int u : G[v] ) {
        if ( color[u] == WHITE )
            dfs_util(u);
        else if ( color[u] == GREY )
            is_back_edge(v, u);
        else if ( color[u] == BLACK )
            is_cross_edge(v, u);
    }
    color[v] = BLACK;
    tout[v] = timer++;
}

void dfs()
{
    fill(color, color + N, WHITE);
    timer = 0;
    for ( int i = 0; i < N; i++)
        if ( color[i] == WHITE )
            dfs_util(i);
}

Topological Sort

bool topo_cmp(const int a, const int b)
{
    /* tout[] is obtained by basic dfs */
    return tout[a] > tout[b];
}

vector<int> topo_sort()
{
    dfs();
    vector<int> topo(N);
    for ( int i = 0; i < N; i++ )
        topo[i] = i;

    // sort the vertices by descending order of the "end time" in DFS
    sort(topo.begin(), topo.end(), topo_cmp);
    return topo;
}

Find bridge

int N;
vector<int> G[MAXN];  // an "undirected graph"

int timer, tin[MAXN], low[MAXN];
bool vis[MAXN];

void is_bridge(int u, int v) {}

void dfs(int v, int parent=-1)
{
    vis[v] = true;
    tin[v] = low[v] = timer++;
    for ( int to : G[v] ) {
        if ( to == parent ) continue;
        if ( vis[to] ) {
            // back edge
            low[v] = min(low[v], tin[to]);
        } else {
            // tree edge
            dfs(to, v);
            low[v] = min(low[v], low[to]);
            if ( low[to] > tin[v] )
                is_bridge(v, to);
        }
    }
}

void find_bridges()
{
    timer = 0;
    fill(vis, vis+N, false);
    for ( int i = 0; i < N; ++i )
        if ( !vis[i] )
            dfs(i);
}