zoukankan      html  css  js  c++  java
  • [学习笔记]tarjan

    强连通分量

    时间复杂度:\(O(n+m)\)
    用途:有向图缩环

    int f[N],dfn[N],low[N],sta[N],top;
    /*dfn[u]:遍历到u点的时间; low[u]:u点可到达的各点中最小的dfn[v],即最高层的点*/
    bool ins[N];
    inline void tarjan(int u){
        dfn[u]=low[u]=++cnt;
        sta[++top]=u;ins[u]=true;
        for(int i=g[u];i;i=e[i].nxt)
            if(!dfn[e[i].to]){
                tarjan(e[i].to);
                low[u]=min(low[u],low[e[i].to]);
            }
            else if(ins[e[i].to])
                low[u]=min(low[u],low[e[i].to]);
        if(dfn[u]==low[u]){
            while(sta[top+1]!=u){
                f[sta[top]]=u;
                ins[sta[top--]]=false;
            }
        }
    }
    inline void solve(){
        for(int i=1;i<=n;i++)
            if(!dfn[i]) tarjan(i);
    }
    

    割边

    割边,又称桥.

    \(dfn[\;],low[\;]\)的定义同\(tarjan\)求有向图强连通分量.

    枚举当前点\(u\)的所有邻接点\(v\):

    1.如果某个邻接点\(v\)未被访问过,则访问\(v\),并在回溯后更新\(low[u]=min(low[u],low[v])\);

    2.如果某个邻接点\(v\)已被访问过,则更新\(low[u]=min(low[u],dfn[v])\).

    对于当前节点\(u\),如果邻接点中存在一点\(v\)满足\(low[v]>dfn[u]\)(\(v\)向上无法到达\(u\)\(u\)祖先)说明\((u,v)\)为一条割边.

    inline void tarjan(int u,int fa){
        dfn[u]=low[u]=++cnt;
        for(int i=g[u];i;i=e[i].nxt)
            if(!dfn[e[i].to]){
                tarjan(e[i].to,u);
                low[u]=min(low[u],low[e[i].to]);
                if(low[e[i].to]>dfn[u]) cut[e[i].n]=true; 
            }
            else if(e[i].to!=fa)
                low[u]=min(low[u],dfn[e[i].to]);
    }
    

    割点

    \(dfn[\;],low[\;]\)的定义同\(tarjan\)求有向图强连通分量.

    枚举当前点\(u\)的所有邻接点\(v\):

    1.如果某个邻接点\(v\)未被访问过,则访问\(v\),并在回溯后更新\(low[u]=min(low[u],low[v])\);

    2.如果某个邻接点\(v\)已被访问过,则更新\(low[u]=min(low[u],dfn[v])\).

    对于当前节点\(u\),

    如果\(u\)为搜索树中的根节点,若它的子节点数\(\geq2\)(根是多棵子树上节点的唯一连通方式),则\(u\)为割点;

    如果\(u\)为搜索树上的非根节点,若存在子节点\(v\)满足\(low[v]\;\geq\;dfn[u]\)(\(v\)向上无法到达\(u\)的祖先),则\(u\)为割点.

    inline void tarjan(int u,int fa){
        dfn[u]=low[u]=++cnt;
        for(int i=g[u];i;i=e[i].nxt){
            ++t[u];
            if(!dfn[e[i].to]){
                tarjan(e[i].to,u);
                low[u]=min(low[u],low[e[i].to]);
                if(u==rt){
                    if(t[u]>=2) cut[u]=true;
                }
                else if(low[e[i].to]>=dfn[u]) cut[u]=true;
            }
            else if(e[i].to!=fa)
                low[u]=min(low[u],dfn[e[i].to]);
        }
    }
    

    2017-01-26 19:18:26

  • 相关阅读:
    关于如何绑定Jquery 的scroll事件(兼容浏览器 Wookmark瀑布流插件)
    HttpHelper类使用方法
    Jquery实现弹出选择框选择后返回,支持多级分类
    让asp.net网站支持多语言,使用资源文件
    关于Android SDK Manager无法获取更新列表的正确设置
    Eclipse使用技巧总结
    配置java环境变量
    sqlserver游标使用和循环
    压缩SQLServer数据库日志的一个存储过程
    Jquery EasyUI封装简化操作
  • 原文地址:https://www.cnblogs.com/AireenYe/p/Tarjan.html
Copyright © 2011-2022 走看看