zoukankan      html  css  js  c++  java
  • Tarjan在图论中的应用(一)——用Tarjan来实现强连通分量缩点

    前言

    (Tarjan)是一个著名的将强连通分量缩点的算法。

    大致思路

    它的大致思路就是在图上每个联通块中任意选一个点开始进行(Tarjan)操作(依据:强连通分量中的点可以两两到达,因此从任意一个点开始都没关系)。

    具体实现

    对于每一个点,先记录它的(dfs),并将该点加入一个栈中,并标记其在栈中,然后用(low[])数组来记录从它出发能到达的字典序最小的节点。

    枚举它所能到达的每一个节点,并对每一个节点进行分类讨论:

    设当前节点为(x),枚举到的节点为(son)

    如果(son)没有被访问过,就先对它进行Tarjan操作,然后更新(low[x])(low[x]=min(low[x],low[son])))。

    如果(son)已经被访问过,又分两种情况:

    • 如果(son)在栈中,那么更新(low[x])

    • 如果(son)不在栈中,那么代表已经对(son)所能到达的每一个节点操作过,说明从(son)不能到达(x),即它们不在同一个强连通分量中,因此不能更新(low[x])

    在枚举完每一个节点后,我们可以判断当前节点是否就是它能到达的dfs序最小的节点,如果是的话,说明它是一个强连通分量中最早被访问过的(当然,也有可能说明它所在的强连通分量中就只有它一个节点),否则,就说明还有比它更早被访问过的,那么退出函数。

    如果当前节点是一个强连通分量中最早被访问到的,那么就说明栈中在它上面的节点全都和它在一个强连通分量中,我们可以新建一个强连通分量,并将它连同在它上面的点全部加入这个强连通分量中即可(加入的同时要注意更新这个强连通分量的信息,可参考例题)。

    代码

    inline void Tarjan(int x)//x是当前访问到的节点
    {
        dfn[x]=low[x]=++d,Stack[++top]=x,vis[x]=1;//记录当前节点的dfs序与当前节点所能到达的dfs序最小的点,将当前节点加入栈中,并标记当前节点在栈中
        for(register int i=lnk[x];i;i=e[i].nxt)//枚举从当前节点出发的每一条边
        {
            if(!dfn[e[i].to]) Tarjan(e[i].to),low[x]=min(low[x],low[e[i].to]);//如果这个节点没访问过,就先对这个节点进行操作,然后更新当前节点能到达的dfs序最小的点
            else if(vis[e[i].to]) low[x]=min(low[x],low[e[i].to]);//否则,如果这个点在栈中,就进行更新
        }
        if(low[x]==dfn[x])//如果当前节点就是当前节点能到达的dfs序最小的点,则对当前强连通分量进行缩点
        {
            a[x].col=++cnt,vis[x]=0;//给当前节点加入一个新的强连通分量,并标记当前节点已出栈(如果需要,还要初始化这个强连通分量的信息,可参考例题)
            while(Stack[top]^x) a[Stack[top]].col=cnt,vis[Stack[top--]]=0;//将栈中当前节点之上的节点一一弹出(如果需要,还要同时更新这个强连通分量的信息)
            --top;//将当前节点弹出
        }
    }
    

    例题

    例题1:【洛谷2403】[SDOI2010] 所驼门王的宝藏

    例题2:【51nod1815】调查任务

  • 相关阅读:
    【Selenium-WebDriver问题点】chromeDriver和chrome浏览器版本之间的兼容性问题
    【Linux】【Jmeter】配置Jmeter服务器和运行Jmeter
    【Linux】【JDK】常用命令使用集和裸机配置JDK步骤。
    【Linux】使用ZStack私有云创建本地Linux服务器
    js基本数据类型和typeof
    Javascript 面向对象编程
    css3作3D旋转视频展示
    css3中的border-radius
    css3中做3D导航栏
    css3动画学习笔记
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/SCC.html
Copyright © 2011-2022 走看看