• Tarjan缩点


    心魔

    塔扬缩点是我长时间不想学的算法了。。。并查集能解决的事绝对不用并查集!!!,然而,随着题目难度加深,我发现有些题目不得不用Tarjan解决,而且现对于并查集而言,思维量可以大大减少,所以这里写下这篇博客,算个纪念吧

    Tarjan是一位非常操蛋帅的人,发明了了大量的算法,什么并查集求LCA啊,什么SPLAY啊...不过最出名的还是他发明的缩点算法

    正文

    首先,什么叫缩点呢?我们需要先理解什么是强连通分量

    强连通分量指的是:在一个有向图中,强联通分量的点可以互相到达,如在下图中,一块黄的就是一个强联通分量

    其实我不太说的清楚原理,直接上代码注释好了:

    int DFN[maxn],LOW[maxn],index;//序号及环开头的序号
    int S[maxn],top;//手写栈
    bool ins[maxn];//是否进栈
    int col[maxn],numc;//染色
    void Tarjan(int u){
        DFN[u] = LOW[u] = ++index;
        S[++top] = u;//进栈
        ins[u] = true;
        for(int i = head[u];i;i = E[i].nxt){
            int v = E[i].v;
            if(!DFN[v]){
                Tarjan(v);
                LOW[u] = min(LOW[u],LOW[v]);//找爸爸(环开头)最小的
                }
            else if(ins[v]){
                LOW[u] = min(LOW[u],DFN[v]);//判断谁是爸爸
                }
            }
        if(DFN[u] == LOW[u]){//发现更新完一轮自己是爸爸
            numc++;
            while(S[top + 1] != u){
                col[S[top]] = numc;//出栈,染色
                ins[S[top--]] = false;
                }
            }
        }
    

    关于Tarjan缩点的技巧

    我们分两种情况:

    1.题目直接考Tarjan(重点)

    这种情况一般是直接考缩点,通常和图论的知识连用,而又以出度入度最为常见

    首先如果原图是一个无向又环图,我们是没办法对其进行某些操作的(比如可以重复走一条路但是点权只加一次这类的),因为要重复访问,所以DFS就毫无用武之地了,这时候我们就需要又Tarjan,在跑Tarjan的时候处理环的某些性质(如点权什么的),在建新图,就可以在新图上进行dp或者遍历了。

    2.题目考其他

    这里不再赘述,Tarjan就是一个辅助作用,把有环图缩为无环图,就可以使用一些算法解决问题了

    最近刷的Tarjan的题:

    P2002 消息扩散 (与入度连用)

    P2341 [HAOI2006]受欢迎的牛 (与出度连用)

    P2746 [USACO5.3]校园网Network of Schools (入度和出度)

    P2863 [USACO06JAN]牛的舞会The Cow Prom (图论知识及对强联通的理解)

    P2835 刻录光盘 (同上)

    P3387 【模板】缩点

  • 相关阅读:
    “北漂”的那些年 5
    “北漂”的那些年 4
    全国省市区代码-2020版
    记一次CDH修改IP
    Python爬取抖音视频
    代码生成,减少70%的重复劳动
    Log4J配置详解
    linux常用命令
    tomcat修改默认访问首页
    java根据身份证号和获取用户年龄和性别的工具类
  • 原文地址:https://www.cnblogs.com/Tony-Double-Sky/p/9285458.html
Copyright © 2020-2023  润新知