码迷,mamicode.com
首页 > 其他好文 > 详细

tarjan(缩点)

时间:2018-09-17 20:32:11      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:传递   强联通   int   程序   强连通   class   时间   ble   需要   

刚做了两道tarjan缩点的题,新学的算法总结一下。

推荐题:(难度单调递增)

[HAOI2006]受欢迎的牛

[USACO5.3]校园网Network of Schools

间谍网络

[APIO2009]抢掠计划

这里不教tarjan,要学的找别的博客吧。

总结:tarjan 简单来说 算法过程 就是找环或单独的点,这就可以构成强联通分量。

代码如下:

void tarjan(int u){
    low[u]=dfn[u]=++cnt;
    stk[++top]=u;
    vis[u]=1;
    for(register int i=head[u];i;i=edge[i].next){
        int v=edge[i].to;
        if(!dfn[v]){
            tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else
        if(vis[v])
        low[u]=min(low[u],dfn[v]);
    }
    if(dfn[u]==low[u]){
        co[u]=++col;
        vis[u]=0;
        while(stk[top]!=u){
        vis[stk[top]]=0;
        co[stk[top]]=col;
        top--;
        }
        top--;
    }
}

缩点也很简单,根据col重新建个图就行了。

tarjan缩点题的一些特征和突破口:

1.一般tarjan缩点的题会给你具有传递性的图,利用传递性可以省略掉一些点,例如:如果a喜欢b,b喜欢c,那么a就喜欢c。假设c又喜欢a,这就可以构成一个强连通分量,缩点即可,没错,这就是“受欢迎的牛”。

2.点的入度和出度是很重要的,很多题就围绕这这个东西去变式,关注点的入度和出度,往往会找到突破口。

3.有的题需要记录一些强连通分量内的数据

(1)可以在同一强连通分量中的点出栈的过程中更新,这样比较方便简单。
(2)也可以在主程序中再次for循环去更新,那样就比较麻烦了,时间复杂度和空间复杂度都得增加,然而我第一次打这类题就是这么操作的,代码90行。

反思:还是理解不够深,我的tarjan总是打错一点,然后又去修改,还是得多模拟一下tarjan缩点的过程。

tarjan(缩点)

标签:传递   强联通   int   程序   强连通   class   时间   ble   需要   

原文地址:https://www.cnblogs.com/sky-zxz/p/9664520.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!