エッジバイコネクトコンポーネント

すべての橋を見つけて、橋を削除します

#include <cstdio> 
#include <iostream> 
using namespace std; 
const int MAXN = 1e5、MAXM = 1e6; 
struct Edge { 
	int from、to、nxt; 
} e [MAXM]; 
int head [MAXN]、edgeCnt = 1; 
void addEdge(int u、int v)
{ 
	e [++ edgeCnt] .from = u; 
	e [edgeCnt] .to = v; 
	e [edgeCnt] .nxt = head [u]; 
	head [u] = edgeCnt; 
} 
int dfn [MAXN]、low [MAXN]、dfnCnt = 0; 
boolブリッジ[MAXM]; 
void tarjan(int x、int in_edge)
{ 
	dfn [x] = low [x] = ++ dfnCnt; 
	for(int i = head [x]; i; i = e [i] .nxt)
	{ 
		int nowV = e [i] .to; 
		if(!dfn [nowV])
		{ 
			tarjan(nowV、i); 
			if(low [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(low [x]、dfn [nowV]); 
		     } 
	} 
} 
int inDcc [MAXN]; 
void dfs(int x、int nowDcc)
{ 
	inDcc [x] = nowDcc; // Xポイントをnowdccに組み込むこの側
	は(int i = head [x]; i; i = e [i] .nxt)
	{ 
		int nowV = e [i] .to; 
		if(inDcc [nowV] || bridge [i])
		/ /サイドのペアに起因する場合、または最初のサイドがブリッジである場合は、
		    継続
		dfs(nowV、nowDcc); 
	} 
} 
int main(){ 
	int n、m; 
	scanf( "%d%d"、&n、 &m); 
	for(int i = 1; i <= m; i ++) 
	{ 
		int u、v;
		scanf( "%d%d"、&u、&v); 
		addEdge(u、v); 
		addEdge(v、u); 
	} 
	for(int i = 1; i <= n; i ++)//すべてのブリッジを検索Out 
		if(!
		    Dfn [i])tarjan(i、0); 
	int nowDcc = 0; 
	for(int i = 1; i <= n; i ++)// iポイントが特定のサイドに割り当てられていない
		場合if( !inDcc [i])
		   dfs(i、++ nowDcc); 
	printf( "%d \ n"、nowDcc); 
	return 0; 
}

  

おすすめ

転載: www.cnblogs.com/cutemush/p/12681811.html