http://poj.org/problem?id=3352
在用Tarjan算法求解连通分量时,通过dfs过程记录每个节点的访问次序,记作dfsnum,存入dfn数组,以及记录一个点可以通过边和回退边可以达到的最小的dfsnum,存入low数组。那么显然,如果对于一个节点u和它的孩子节点v,v可以通过回退边达到比dfn[u]小的dfsnum,即说明即使删除边(u,v),v仍然可以到达u的祖先节点,即说明(u,v)不是桥。所以在dfs过程中得到一条树边(u,v)有low[v]>dfn[u]时,则可以得到(u,v)是一座桥。
求出桥之后,那么删掉图中所有的桥,就可以得到剩下所有的双连通分量。 这道题目的意思是,给一个无向图,问至少添加几条边可以使这个图变成双连通分量。刚才已经分析了求桥的方法,删掉桥后得到所有的双连通分量,这时候可以把每个双连通分量看成一个点。将所有的双连通分量缩成一个点后得到的是一棵树,对一个树形无向图,显然,只需添加(度数为1点的个数+1)/2即可将图变成双连通的。
至于如何双连通所点,可以用dfs搜索一遍,每次dfs除非搜到之前求出的桥,否则继续根据连边继续搜索,并将其标号,这样就将图中删掉所有桥后的所有双连通分量标出了各自的序号。最后再求出度数为1的双连通缩点的个数,即可得到答案。
代码:
// Header.
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include