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

tarjan进阶

时间:2018-08-23 20:57:59      阅读:157      评论:0      收藏:0      [点我收藏+]

标签:tarjan   style   割点   continue   无向图   turn   strong   code   返回   

一、边双连通分量

定义

若一个无向图中的去掉任意一条边都不会改变此图的连通性,即不存在桥,则称作边双连通图。一个无向图中的每一个极大边双连通子图称作此无向图的边双连通分量。

实际求法和强连通分量差不多,只是要注意由于一条无向边被分为两条有向边存储,所以在经过其中一条从u到达v之后不能再通过另一条边由v返回u。

代码

inline void tarjan(int x,int fa){
      dfn[x]=low[x]=++cnt;
      a.push(x);
      ist[x]=1;
      int wh=0;
      for(int i=0;i<v[x].size();i++){
            if(v[x][i]==fa&&!wh){
              wh=1;
              continue;
            }
          if(!dfn[v[x][i]]){
            tarjan(v[x][i],x);
            low[x]=min(low[x],low[v[x][i]]);
          }else if(ist[v[x][i]]){
            low[x]=min(low[x],dfn[v[x][i]]);
          }
        }
      if(dfn[x]==low[x]){
          sum++;
          while(1){
            int u=a.top();
            a.pop();
            ist[u]=0;
            belong[u]=sum;
            if(u==x)break;
          }
      }
      return;
}

二、割点

定义

在一个无向图中,如果有一个顶点集合,删除这个顶点集合以及这个集合中所有顶点相关联的边以后,图的连通分量增多,就称这个点集为割点集合。

也就是说对于一条边的两个节点u和v,如果low[v]>=dfn[u]则u是一个割点(dfn[u]<dfn[v])。

代码

inline void tarjan(long long x,long long fa){
      dfn[x]=low[x]=++cnt;
      long long son=0;
      for(long long i=0;i<v[x].size();i++)
        if(v[x][i]!=fa){
          if(!dfn[v[x][i]]){
            son++;
            tarjan(v[x][i],x);
            low[x]=min(low[x],low[v[x][i]]);
            if(low[v[x][i]]>=dfn[x])is[x]=1;
          }else low[x]=min(low[x],dfn[v[x][i]]);
        }
      if(!fa&&son==1)is[x]=0;
      return;
}

 

tarjan进阶

标签:tarjan   style   割点   continue   无向图   turn   strong   code   返回   

原文地址:https://www.cnblogs.com/yzxverygood/p/9525924.html

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