// 集光点と成分Tuqiang通信するためTarjanアルゴリズム の#include <iostreamの> する#include <cstdioを> する#include <CStringの> する#include <アルゴリズム> の#include <ベクトル> の#include <キュー> 使用して 名前空間、STD のconst int型 = N 100010、M = 1000010 ; // INT 版[M]、次に[M]、ヘッド[N]、DFN [N]、低[N]; int型スタック[N]、INS [N]、C [N ]; int型; VC [m]は、NC [m]は、HC [N]、TC // 強連結成分 ベクトル< int型 > SCC [N]; int型のn、M、TOT、NUM、トップ、CNT; ボイド追加(INTの X、int型Y){ 版[ ++ TOT = Y、次に[TOT =頭部[X]、ヘッド[X] = TOT; } // 図の点構築凝縮後の ボイド add_cを(INT X、INT Y){ VC [ ++ TC = Y、NC [TC] = HC [X]、HC [X] = TC; } ボイド Tarjan(INT X){ DFN [X] =低[X] ++ = NUM ; スタック[ ++トップ] X =、INSは、[X] = 1 ; // タグ点x のための(int型 ; I Iは=私は=ヘッドが[X] 次に[I]は) // 渡されない 場合(!{DFN [版[I]) Tarjan(版[I]); // 再帰更新 低[X] = 分(低[X]、低[版[I]); } そう IF (INS [版[I]]) // 直接更新 [=] Xローに分(低[X]はDFN [版[I、]]); IF(DFN [X] == 低[X]){ // 強連結 ++ CNT; INT Y; DO { Y =スタック[top--]、INS [Y] = 0 ; // 強連結するためにどの属し C [Y] = CNT、SCC [CNT] .push_back(Y); } 一方(!X = Y)。 } } int型のmain(){ CIN >> N >> M。 以下のために(int型 I = 1 ; I <= M; iは++ ){ int型のX、Y。 scanf関数(" %dの%のD "、およびX&Y)。 (x、y)を加えます。 } のために(int型 I = 1は iが++; iがn = < ) であれば(!tarjan(I)DFN [I])。 用(INT X = 1 ; X <= nであり; x ++ ) のために(int型 I =ヘッド[X]。私; I = [I]){次に INT Y = 版[I]; もし(C [X] == C [Y])続けます。 add_c(C [X]、C [Y])。 } }