Componente biconconectado de borde

Descubra todos los puentes, luego retire el puente

#include <cstdio> 
#include <iostream> 
usando el espacio de nombres std; 
const int MAXN = 1e5, MAXM = 1e6; 
struct Edge { 
	int de, a, nxt; 
} e [MAXM]; 
int head [MAXN], edgeCnt = 1; 
addEdge vacío (int u, int v) 
{ 
	e [++ edgeCnt] .from = u; 
	e [edgeCnt] .to = v; 
	e [edgeCnt] .nxt = cabeza [u]; 
	head [u] = edgeCnt; 
} 
int dfn [MAXN], bajo [MAXN], dfnCnt = 0; 
puente de bool [MAXM]; 
nulo tarjan (int x, int in_edge) 
{ 
	dfn [x] = bajo [x] = ++ dfnCnt; 
	for (int i = head [x]; i; i = e [i] .nxt) 
	{ 
		int nowV = e [i] .to; 
		if (! dfn [nowV]) 
		{ 
			tarjan (nowV, i); 
			if (bajo [nowV]> dfn [x])
			{ 
				bridge [i] = bridge [i ^ 1] = 1; 
			} 
			low [x] = min (low [x], low [nowV]); 
		} 
		else 
		    if (i! = (in_edge ^ 1)) 
		     { 
			     low [ x] = min (bajo [x], dfn [nowV]); 
		     } 
	} 
} 
int inDcc [MAXN]; 
void dfs (int x, int nowDcc) 
{ 
	inDcc [x] = nowDcc; // El punto X es nowd Este lado se duplica 
	para (int i = head [x]; i; i = e [i] .nxt) 
	{ 
		int nowV = e [i] .to; 
		if (inDcc [nowV] || bridge [i]) 
		/ / Si se ha atribuido a un par de lados, o el primer lado es un puente, 
		    continúe; 
		dfs (nowV, nowDcc); 
	} 
} 
int main () { 
	int n, m; 
	scanf ("% d% d", & n, & m); 
	para (int i = 1; i <= m; i ++) 
	{ 
		int u, v;
		scanf ("% d% d", & u, & v); 
		addEdge (u, v); 
		addEdge (v, u); 
	} 
	para (int i = 1; i <= n; i ++) // Buscar todos los puentes Fuera 
		si (! 
		    Dfn [i]) tarjan (i, 0); 
	int nowDcc = 0; 
	for (int i = 1; i <= n; i ++) // si el punto no se ha asignado a un lado determinado 
		if ( ! inDcc [i]) 
		   dfs (i, ++ nowDcc); 
	printf ("% d \ n", nowDcc); 
	return 0; 
}

  

Supongo que te gusta

Origin www.cnblogs.com/cutemush/p/12681811.html
Recomendado
Clasificación