tarjan算法求联通块中求割点和割边

来自hiho的第五十二周,参考链接:http://hihocoder.com/contest/hiho52/problem/1


//tarjan中可见dfs_pos,low数组不需要初始化
//如果有多个联通分块,那么就要枚举每个未访问过的点进行tarjan,进行tarjan前先将fa[i] = -1
//这里的se为set,存放割点;edge为vector<pair<int,int> >,存放割边
void tarjan(int u)
{	
	int num_son = 0;//以当前点为树根的子树的个数
	vis[u] = 1;
	dfs_pos[u] = low[u] = ++jishu;//dfs_pos为dfs序,low[u]是dfs序最小的祖先(没有则为自己)
	for(int i = head[u];~i;i = e[i].nex)
	{
		int v = e[i].v;
		if(!vis[v])
		{
			num_son++;
			fa[v] = u;//fa是父亲
			tarjan(v);
			low[u] = min(low[u],low[v]);//递归求dfs序最小的的祖先
			if(fa[u] == -1 && num_son > 1)//若当前节点没有父亲且有两个或两个以上子树,则这个点必为割点
				se.insert(u);
			if(fa[u] != -1 && low[v] >= dfs_pos[u])//若当前点存在父亲,且他的儿子中没有回边连到u或者u的祖先中,此点为割点
				se.insert(u);
			if(low[v] > dfs_pos[u])//他的儿子没有回边连到u的祖先中
				edge.push_back(pii(min(u,v),max(u,v)));
		}
		else if(v != fa[u])//如果拜访到已经被访问的点
			low[u] = min(low[u],low[v]);
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值