c_cpp Tarjan SCC(导演)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp Tarjan SCC(导演)相关的知识,希望对你有一定的参考价值。

#define UNVISITED -1

int depth, num_scc;
vi num, lo, stk, vis;
vvi g;

// Tarjan's algorithm to find SCC's of directed graph; O(V+E).
// --> commonly used for pre-processing to contract digraph to DAG
void scc(int u) {
  lo[u] = num[u] = depth++; // lo[u] <= num[u]

  // push 'u' onto stack, and track explored vertices with 'vis'
  stk.push_back(u);
  vis[u] = 1;
  for (auto &v : g[u]) {
    if (num[v] == UNVISITED)
      scc(v); // this part is amortized O(V)

    // Condition to update:
    if (vis[v])
      lo[u] = min(lo[u], lo[v]);
  }

  // if root, i.e. start of an SCC
  // Since only visited vertices may update lo[u], and initally we set lo[u] =
  // num[u], then if lo[u] == num[u], we know 'u' is the root of this SCC.  To
  // access the members of this SCC, pop from our "stack" (i.e. 'stk', as
  // vector), up to (and including) root 'u'.
  if (lo[u] == num[u]) {
    cout << "SCC #" << ++num_scc << ":";
    for (;;) {
      int v = stk.back();
      stk.pop_back();
      vis[v] = 0;
      cout << " \n"[u == v] << v;
      if (u == v)
        break;
    }
  }
}

int main() {

  // Number of vertices
  int V;
  V = 10;

  // Build adjacency list
  g.assign(V, vi());
  // ...

  depth = num_scc = 0;
  num.assign(V, UNVISITED);
  lo.assign(V, 0);
  vis.assign(V, 0);
  REP(i, V) {
    if (num[i] == UNVISITED) {
      scc(i);
    }
  }

  return 0;
}

以上是关于c_cpp Tarjan SCC(导演)的主要内容,如果未能解决你的问题,请参考以下文章

tarjan scc

受欢迎的牛 tarjan求scc模板

强连通分量——间谍网络(洛谷_1262)——tarjan求scc

强连通分量——消息扩散(洛谷_2002)——tarjan求scc

Tarjan算法 有向图SCC

强连通分量——爱在心中(codevs_2822)——tarjan求scc