zoukankan      html  css  js  c++  java
  • 初学强连通(Tarjan)

    首先我们要对强连通分量有个定义,何为强连通?

      如果一个图的子图中,任意两点可以相互到达,那么这就组成了一个强连通分量。

      一般强连通都是在有向图的情况下讨论的,因为在无向图中只要这个图连通这整个图就是一个强连通图,而在有向图中,只有子图成环,才会出现强连通分量的情况,因此tarjan缩点算法一般用于处理成环有向图的问题。

    Tarjan算法思想

      Tarjan算法是基于对图深度优先搜索的算法。首先要理解的是两个数组:dfn 数组和 low 数组,其中 dfn 数组是代表第 i 个节点在 dfs 序上是第几个被遍历到,low [u] 则表示为以 u 为起点进行 dfs 所能经过点中最小的 dfs 序,即最小的 dfn [i],所以当 dfn [u] == low [u]时,说明出现环了,这时换种任意一点都能到达环上其他点,因此这就是个强连通分量。

      图解(转自https://www.cnblogs.com/five20/p/7594239.html

    算法模板

    int deep,num;
    int dfn[MAXN],low[MAXN],vis[MAXN],col[MAXN];
    vector<int>G[MAXN];
    stack<int>s;
    inline void Tarjan(int u){
        deep++;
        dfn[u]=low[u]=deep;
        vis[u]=1;
        s.push(u);
        for(auto v:G[u]){
            if(!dfn[v]){
                Tarjan(v);
                low[u]=min(low[u],low[v]);
            }
            else if(vis[v])low[u]=min(low[u],dfn[v]);
        }
        if(low[u]==dfn[u]){
            col[u]=++num;
            vis[u]=0;
            while(s.top()!=u){
                col[s.top()]=num;
                vis[s.top()]=0;
                s.pop();
            }
            s.pop();
        }
    }
    int main()
    {
        scanf("%d %d",&n,&m);
        for(int i=1,u,v;i<=m;i++){
            scanf("%d %d",&u,&v);
            G[u].push_back(v);
        }
        for(int i=1;i<=n;i++){
            if(!dfn[i])Tarjan(i);
        for(int i=1;i<=n;i++)
            printf("******%d %d
    ",i,col[i]);
        //最后的col数组就代表缩完点后每个点的归属
    }
  • 相关阅读:
    MVC3 中上传大文件
    js 将十进制转换为八位二进制数组
    nodejs 读取并处理二进制文件
    freeswitch源码编译 ./configure 遇到的问题
    通道设置静态坐席
    呼叫中心静态座席的配置
    ECharts报表
    combotree
    openlayer PanZoom
    为什么要始终使用PreparedStatement代替Statement?
  • 原文地址:https://www.cnblogs.com/Mmasker/p/12011642.html
Copyright © 2011-2022 走看看