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);
    }
  • 相关阅读:
    C#遍历DataSet中数据的几种方法总结
    angularjs作用域
    SQL 语句日期用法及函数
    Sublime Text3 快捷键汇总
    AngularJS 最常用的功能
    C#中如何排除/过滤/清空/删除掉字符串数组中的空字符串
    AngularJS的指令用法
    [WCF REST] Web消息主体风格(Message Body Style)
    泛型
    语法补充
  • 原文地址:https://www.cnblogs.com/TreeDream/p/6075246.html
Copyright © 2011-2022 走看看