无向图的割点和桥 tarjan 模板

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 20005;
const int MAXM = 100005;
int n, m, fir[MAXN], nxt[MAXM<<1], to[MAXM<<1], cnt=1;

int dfn[MAXN], low[MAXN], tot;
int cur, Ans[MAXN];
bool is_bridge[MAXM<<1];

void tarjan(int u, int ff)
{
	dfn[u] = low[u] = ++tot;
	int out = 0; bool flag = 0;
	for(int i = fir[u]; i; i = nxt[i])
		if(!dfn[to[i]])
		{
			out++, tarjan(to[i], i), low[u] = min(low[u], low[to[i]]);
			if(dfn[u] <= low[to[i]]) flag = 1; //存割点
            if(dfn[u] < low[to[i]]) is_bridge[i] = 1; //存桥
		}
		else if((i^1) != ff) low[u] = min(low[u], dfn[to[i]]);
	if(!ff && out == 1) flag = 0;
	if(flag) Ans[++cur] = u;
}

void Add(int u, int v) { to[++cnt] = v; nxt[cnt] = fir[u]; fir[u] = cnt; }

int main ()
{
	int x, y;
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= m; i++)
		scanf("%d%d", &x, &y), Add(x, y), Add(y, x);
	for(int i = 1; i <= n; i++)
		if(!dfn[i]) tarjan(i, 0);
	printf("%d
", cur);
	sort(Ans + 1, Ans + cur + 1);
	for(int i = 1; i <= cur; i++) // 输出割点
		printf("%d%c", Ans[i], i == n ? '
' : ' ');
}
原文地址:https://www.cnblogs.com/Orz-IE/p/12039497.html