すべての橋を見つけて、橋を削除します
#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; }