Tarjan 算法求无向图的割顶和桥

Posted ioioioioioio

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Tarjan 算法求无向图的割顶和桥相关的知识,希望对你有一定的参考价值。

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;
const int N = 250;

int head[N], low[N], dfn[N], fa[N];
int n, m, now = 1, Tarjan_clock;
bool is_cut[N];
struct Node{
	int u, v, nxt;
}E[N];

inline int read()
{
	int x = 0; char c = getchar();
	while(c < ‘0‘ || c > ‘9‘) c = getchar();
	while(c >= ‘0‘ && c <= ‘9‘) x = x * 10 + c - ‘0‘, c = getchar();
	return x;
}

inline void add(int u, int v)
{
	E[now].v = v;
	E[now].nxt = head[u];
	head[u] = now ++;
}

void Tarjan(int x, int fa_x)
{
	low[x] = dfn[x] = ++ Tarjan_clock;
	fa[x] = fa_x;
	for(int i = head[x]; ~ i; i = E[i].nxt)
	{
		int v = E[i].v;
		if(!dfn[v])
		{
			Tarjan(v, x);
			low[x] = min(low[x], low[v]);
		}
		else
			if(v != fa_x)
				low[x] = min(low[x], dfn[v]);
	}
}

inline void August_13th()
{
	int root_son = 0;
	Tarjan(1, 0);
	for(int i = 2; i <= n; i ++)
	{
		int fa_i = fa[i];
		if(fa_i == 1)
			root_son ++;
		else 
			if(low[i] >= dfn[fa_i])
				is_cut[fa_i] = 1;
	}
	if(root_son > 1)
		is_cut[1] = 1;
	for(int i = 1; i <= n; i ++)
		if(is_cut[i])
			printf("%d\n", i);
	for(int i = 1; i <= n; i ++)
	{
		int fa_i = fa[i];
		if(fa_i > 0 && low[i] > dfn[fa_i])
			printf("%d,%d\n",fa_i,i);
	}
}

int main()
{
	n = read();
	m = read();
	for(int i = 1; i <= n; i ++)
		head[i] = -1;
	for(int i = 1; i <= m; i ++)
	{
		int u = read();
		int v = read();
		add(u, v);
		add(v, u);
	}
	August_13th();
	
	
	return 0;
}

  

以上是关于Tarjan 算法求无向图的割顶和桥的主要内容,如果未能解决你的问题,请参考以下文章

无向图的割顶和桥,无向图的双连通分量入门详解及模板 -----「转载」

无向图的割顶和桥

2018/2/11 每日一学 无向图割顶和桥

DFS的运用(二分图判定无向图的割顶和桥,双连通分量,有向图的强连通分量)

连通图基本知识

无向图求割顶和桥总结