• 有向图求强连通分量


    在图中找到一个最大的子图,使这个子图中每个两点都能够互相到达,这个最大的子图称为强连通分量,同时一个点也是属于强连通分量的。主要是通过dfs来实现的,在dfs的过程中维护了几个东西:一个stack用来存访问过的节点,就是靠栈来存的强连通分量的节点的,要一个dfn数组用于记录节点的时间戳,每个节点的dfn值是不会变的,还有最后一个是low数组,我的理解是对于low[i]来说,low[i]记录的是包含了i节点的强连通分量(也可以理解为强连通分量树)的根节点的dfn值,也可以理解为i通过i子树里的点能访问到的dfs树里最早的节点。

    1,2,3为一个scc,4为一个scc,5为一个scc

    int n,sccn,cnt,dfn[105],low[105],scc[105];//sccn记录scc个数,scc【i】记录i属于的scc
    vector<int>g[105];
    stack<int>sta;
    
    void dfs(int now){
        dfn[now]=low[now]=++cnt;
        sta.push(now);
        for(int i=0;i<(int)g[now].size();i++){
            int v=g[now][i];
            if(!dfn[v]){
                dfs(v);
                low[now]=min(low[now],low[v]);
            }else if(!scc[v]){
                low[now]=min(low[now],dfn[v]);
            }
        }
        if(low[now]==dfn[now]){//缩点操作,把图缩为sccn个点,要得到新图的话,枚举原来的边,然后如果两个点对应的scc不同则连边
            sccn++;
            for(;;){
                int tmp=sta.top();sta.pop();
                scc[tmp]=sccn;
                if(tmp==now) break;
            }
        }
    }

    推荐一篇入门博客https://blog.csdn.net/qq_34374664/article/details/77488976

  • 相关阅读:
    Postman几种常用方式
    PL/SQL 循环结构
    【oracle】解锁oracle用户,unlock
    四则运算题2
    有关Botton的用法(一)
    SQLiteOpenHelper的使用
    用Toast来增加调试效率的小技巧
    汇编语言-比较字符串
    正向代理和反向代理
    redis安装与配置
  • 原文地址:https://www.cnblogs.com/eason9906/p/11755014.html
Copyright © 2020-2023  润新知