zoukankan      html  css  js  c++  java
  • Tarjan

    一、Tarjan算法求LCA

    二、Tarjan算法求强连通分量【栈里存点---------每个点都属于一个强连通分量】

    (着重理解一下第11行的else if语句:dfn[ i ]!=0 且 instk[i]==0的点一定已经是另一个强连通分量里面的点了,所以就不用考虑了,所以用else if(instk[ i ])来判断是不是已经是别的强连通分量里的点了,如果不是,则是当前点的祖先,可以用来更新low[ u ],这也是强连通分量的更新low[ u ]的精髓。)

     1 void Tarjan(int u) {
     2     dfn[u] = low[u] = ++tim;
     3     in_stk[u] = 1;
     4     stk[tp++] = u;
     5     for (int i = head[u]; i != -1; i = e[i].next) {
     6         int v = e[i].to;
     7         if (!dfn[v]) {
     8             Tarjan(v);
     9             if (low[v] < low[u])low[u] = low[v];
    10         }
    11         else if (in_stk[v]) {
    12             if (low[v] < low[u])low[u] = low[v];//这里使用dfn[v]和low[v]都可以
    13         }
    14     }
    15     if (dfn[u] == low[u]) {
    16         scc_cnt++;
    17         do {
    18             tp--;
    19             int tt = stk[tp];
    20             col[tt] = scc_cnt;
    21             in_stk[tt] = 0;
    22             vc[scc_cnt].push_back(tt);
    23         } while (stk[tp] != u);
    24     }
    25 }

    三、Tarjan算法求双连通分量【栈里存边------每条边都属于一个点双连通分量】

    (由于是无向图,这里需要注意的是不能重复访问边,用else if(dfn[ u ]>dfn[ v ]&&v!=fa)来防止重复访问)

     1 void Tarjan(int u, int fa) {
     2     dfn[u] = low[u] = ++tim;
     3     int child = 0;
     4     for (int i = head[u]; i != -1; i = e[i].next) {
     5         int v = e[i].to;
     6         struct edge e1;
     7         e1.fr = u; e1.to = v;
     8         if (!dfn[v]) {
     9             stk.push(e1);
    10             child++;
    11             Tarjan(v);
    12             if (low[v] >= dfn[u]) {
    13                 iscut[u] = true;
    14                 bcc_cnt++; bcc[bcc_cnt].clear();
    15                 do {
    16                     struct edge e2 = stk.top(); stk.pop();
    17                     if (col[e2.fr]!=bcc_cnt) {
    18                         bcc[bcc_cnt].push_back(e2.fr);
    19                         col[e2.fr] = bcc_cnt;
    20                     }
    21                     if (col[e2.to]!=bcc_cnt) {
    22                         bcc[bcc_cnt].push_back(e2.to);
    23                         col[e2.to] = bcc_cnt;
    24                     }
    25                 } while (e2.fr != u || e2.to != v);
    26             }
    27         }
    28         else if (dfn[v] < dfn[u] && v != fa) {
    29             stk.push(e1);
    30             low[u] = min(low[u], dfn[v]);//注意这里必须是dfn[v],而不能是low[v],因为low[v]很可能在另一个双连通分量已经被更新,这个时候用会出错
    31         }
    32         if (fa < 0 && chile == 1)iscut[u] = false;
    33     }
    34 }
  • 相关阅读:
    Internal Server Error处理程序“PageHandlerFactory-Integr”在其模块列表中有一个错误模块“ManagedPipelineHandler”
    OpenGL学习(4)——纹理
    OpenGL学习(3)——Shader(补)
    OpenGL学习(3)——Shader
    OpenGL学习(2)——绘制三角形(补)
    OpenGL学习(2)——绘制三角形
    OpenGL学习(1)——创建窗口
    PHP框架对地址进行Dispatch的思考
    OJ练习47——T12 Integer to Roman
    OJ练习46——T11 Container With Most Water
  • 原文地址:https://www.cnblogs.com/MekakuCityActor/p/9642896.html
Copyright © 2011-2022 走看看