双连通分量(上):割点

废话

其实这一部分不应该叫做双连通分量的(或许叫做割点和桥会好一点)


定义

我们先看看度娘给的定义:在无向联通图 G=(V,E)中: 若对于x∈V, 从图中删去节点x以及所有与x关联的边之后, G分裂成两个或两个以上不相连的子图, 则称x为G的割点。 简而言之, 割点是无向联通图中的一个特殊的点, 删去中这个点后, 此图不再联通。
你一定看懂了
只是我太笨了,所以还得说两嘴,你可以把割点想成必经点(但是不是起点、终点)。


思路

首先,求割点数量需要用Tarjin(废话),几乎和求强连通分量一样的代码,只是需要加一个判断。
一个点是割点的状况有两种:
①是一个根,而且有不止一个子树。
②他的儿子节点(们)回溯不能回到比他小的点上面去(换句话说,没了他这个点,他的儿子们就回不去了)。
即:

(rt==k&&cntt>1)||(rt!=k&&low[a[i].to]>=dfn[k])

所以求割点的代码就长这样:

stack<int> st;
void tarjin(int k)
{
  dfn[k]=low[k]=++tot,st.push(k);
  int cntt=0;
  for(int i=head[k]; i; i=a[i].nxt)
    if(!dfn[a[i].to])
    {
      cntt++,tarjin(a[i].to),low[k]=min(low[k],low[a[i].to]);
      if((rt==k&&cntt>1)||(rt!=k&&low[a[i].to]>=dfn[k])) cp[k]=1;
    }
    else low[k]=min(low[k],dfn[a[i].to]);
}

小结

没啥好小结的,就一个词+一句话:Tarjin+两个条件


完结撒花!!!
别忘了点赞关注,谢谢!!

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容