zoukankan      html  css  js  c++  java
  • tarjan

    如果两个点可以互相到达,则称为强连通。如果有向图G每个点都可以互相到达,则称为强连通图。其中G中的极大强连通子图,则称为强连通分量。
    现求强连通分量是多少,且哪些点属于同一个强连通分量

    tarjan由dfs,dfn[i],low[i],stack组成
    dfs是遍历方式
    dfn[i]:时间戳(客观上dfs遍历时每到达一个新节点序号就+1,覆盖一次就不变了)
    low[i]:指原本时间戳被更小的时间戳覆盖

    不多bb,看图说话:

     摘自大佬博客:

    https://www.cnblogs.com/shadowland/p/5872257.html

    没错,若dfn[i]=low[i],那么i和i的子树(stack栈回溯实现)就构成一个强连通分量

    上代码: 

    int idx=0;//总的dfn_num
    bool vis[N];
    int ans=0;//总的强连通分量数
    
    void tarjan(int u){
    dfn[u]=low[u]=++tot;
    vis[u]=true; //判断是否在栈中
    stack[++top]=x;
    for(i,fi[u],nx){
    int v=e[i].to;
    if(!dfn[v])tarjan(v),chkmin(low[u],low[v]);//如果是个新节点,就dfs,回溯时记得更新low(因为是可能属于同一个强连通分量)
    else if(vis[v])chkmin(low[u],dfn[v]);//出现这个证明已经找到目标了,返回目标的时间戳dfn
    }
    if(dfn[u]==low[u]){//1.栈回溯,2.同一强连通分量染色,3.栈清空
    ans++;
    while(stack[top+1]!=u){
    color[stack[top]]=ans;
    vis[stack[top--]]=false; }}}
  • 相关阅读:
    文章分类
    多项式笔记(二)
    P7102 [w3R1] 算
    P3711 仓鼠的数学题
    常见特殊数的多项式求法
    P4091 [HEOI2016/TJOI2016]求和
    CF961G Partitions
    P4609 [FJOI2016]建筑师
    P5401 [CTS2019]珍珠
    P5162 WD与积木
  • 原文地址:https://www.cnblogs.com/planche/p/9388422.html
Copyright © 2011-2022 走看看