图论Tarjan求割点与桥

使用Tarjan方法计算割点与桥,这里先介绍下概念。

无向连通图中,如果删除某点后,图变成不连通,则称该点为割点。
无向连通图中,如果删除某边后,图变成不连通,则称该边为桥。

一个顶点u是割点,当且仅当满足(1)或(2)
(1) u为树根,且u有多于一个子树。

(2) u不为树根,且满足存在(u,v)为树枝边(或称父子边,即u为v在搜索树中的父亲),使得dfn(u)<=low(v)。
一条无向边(u,v)是桥,当且仅当(u,v)为树枝边,且满足dfn(u)<low(v)(前提是其没有重边所以先用邻接矩阵存储)。


void Tarjan(int u, int father) //father 是u的父节点
{	
	Father[u] = father;
	int i,j,k;
	low[u] = dfn[u] = nTime ++;
	for( i = 0;i < G[u].size() ;i ++ ) {
		int v = G[u][i];
		if( ! dfn[v]) {
			Tarjan(v,u);
			low[u] = min(low[u],low[v]);
                        if(low[u]>low[u]) u,v为桥
 }
		else if( father != v ) //连到父节点的回边不考虑,否则求不出桥
			low[u] = min(low[u],dfn[v]);
	}
}
void Count()
{ //计算割点和桥
    int nRootSons = 0;    int i;
    Tarjan(1,0);
    for( i = 2;i <= n;i ++ ) {
        int v = Father[i];
        if( v == 1 )
            nRootSons ++; //DFS树中根节点有几个子树
        else {
            if( dfn[v] <= low[i])
                bIsCutVetext[v] = true;
        }
    }
    if( nRootSons > 1)
        bIsCutVetext[1] = true;
    for( i = 1;i <= n;i ++ )
        if( bIsCutVetext[i] )
            cout << i << endl;
    for( i = 1;i <= n;i ++) {
        int v = Father[i];
        if(v >0 &&  dfn[v] < low[i])
            cout << v << "," << i <<endl;
    }
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值