废话
其实这一部分不应该叫做双连通分量的(或许叫做割点和桥会好一点)
定义
我们先看看度娘给的定义:在无向联通图 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+两个条件
完结撒花!!!
别忘了点赞,关注,谢谢!!