zoukankan      html  css  js  c++  java
  • 有向图的强连通分量——Tarjan

    在同一个DFS树中分离不同的强连通分量SCC;

    考虑一个强连通分量C,第一个被发现的点是 x,希望在 x 访问完时立刻输出 C,这样就可以实现 在同一个DFS树中分离不同的强连通分量了。

    问题就转换为判断,一个点是否 是 第一个被发现的点,这样,可以利用之前的 点-双连通分离的数据结构, lowlink(u) 函数,为 u 及其后代能追溯到的最早祖先。

    当 lowlink(u) == pre[u] (进树的时间),那么这个点 U 就是第一个被发现的点。那么这个 强连通分量就出来了。

    #include <bits/stdc++.h>
    using namespace std;
    
    const int Maxn = 1000;
    
    vector<int> G[Maxn];
    int pre[Maxn];
    int lowlink[Maxn];
    int sccno[Maxn];
    int dfs_clock,scc_cnt;
    
    stack<int> S;   //点集
    
    void dfs(int u)
    {
        lowlink[u] = pre[u] = ++dfs_clock;
        S.push(u);
        for(int i=0; i<G[u].size(); i++)
        {
            int v = G[u][i];
            if(!pre[v])
            {
                dfs(v);
                lowlink[u] = min(lowlink[u],lowlink[v]);
            }
            else if(!sccno[v])
            {
                lowlink[u] = min(lowlink[u],pre[v]);
            }
        }
        if(lowlink[u]==pre[u])
        {
            scc_cnt ++;
            for(;;)
            {
                int x = S.top();
                S.pop();
                sccno[x] = scc_cnt;
                if(x==u) break;
            }
        }
    }
    
    void find_scc(int n)
    {
        dfs_clock = scc_cnt = 0;
        memset(sccno,0,sizeof(sccno));
        memset(pre,0,sizeof(pre));
        for(int i=0; i<n; i++)
            if(!pre[i])
                dfs(i);
    }
  • 相关阅读:
    word上怎么打钩
    POI操作excel常用方法总结
    web.xml中Filter过滤器标签说明
    IDEA使用操作说明(自己总结)
    windows 64位上oracle 11g安装
    List<T>与List<?>的区别
    java分页之假分页
    CDN之Web Cache
    HTTP之缓存技术
    HTTP之Cookie和Session
  • 原文地址:https://www.cnblogs.com/TreeDream/p/6075246.html
Copyright © 2011-2022 走看看