問題の説明
方向の小さなギリシャの感覚を訓練するために、ガルドンは室内N(N <= 10000)及びMチャネル(Mは<= 100000)、各チャネルが呼び出された場合には、一方向性であり、大規模な城を建て部屋Aと部屋Bの連通路は、部屋Bには、このチャネルを介して説明した客室でのみ到達することができますが、それを介してBの部屋に到達することができます部屋を示すものではありません。任意のiとjのために、部屋から部屋jへの少なくとも一つのパスがあるi、jはまた、部屋からのパスをしている可能性がありますガルドンは、すなわち、任意の二つの部屋が相互接続されているかどうかを確認するためのプログラムを書くことをお願いする必要があります部屋私。
入力
N及びM、次のMラインの各2つの数AおよびBと、Bの部屋の部屋からチャネルを表すことができる:最初の行は、2つの入力数値があり、入力データの複数のセットを含みます。2ゼロでファイルと終了。
出力
任意の二つの部屋を互いに、および出力に接続されている場合、入力データの各セットに対して、「はい」、そうでない場合、「いいえ」を出力します。
サンプル入力
3 3
1 2
2 3
3 1
3 3
1 2
2 3
3 2
0 0
サンプル出力
はい
ノー
各データセットの分析図が強く、図に接続されていません。
強連結成分に統計数が1でないとして
1の#include <cstdioを> 2の#include <ベクトル> 3の#include <CStringの> 4の#include <アルゴリズム> 。5 使用 名前空間STD; 6 7。 INTトップ; /// スタック 8 のconst int型 MAXN = 1E5 + 。5 ; 9 INTスタック【MAXN]; /// アナログスタック 10 BOOL inStack [MAXN]; /// 判定がスタックしていない 。11 /// DFNは、DFSトラバーサル順序、一次数uはにさかのぼることができるノードに低いスタックであります 12は、 INT DFN [MAXN]、低[MAXN]; 13である INT CNT、インデックス;/// CNTは、DFSするインデックストラバーサル順序強連結成分の数を数える 14ベクトル< INT >を[MAXN] VEC; 15 16 ボイドのinit(){ 17。 トップ= CNT =インデックス= 0 ; 18である のmemset(DFN、 - 1。、はsizeofのDFN)は、 図19 のmemset(inStack、falseに、はsizeofのinStack); 20である ため(INT I = 1 ; I ++は、私はMAXN < ){ 21は VEC [I] .clear(); 22である } 23である } 24 25 空隙 Tarjanを(int型U){ 26 のint = V 0 。 27の DFN [U] =低[U] = ++ 指数; 28 inStack [U] = 真。 29 スタック[++トップ] = U。 30 int型 T = VEC [U] .size()。 31 のために(int型 i = 0 ; iがTを<; Iは++ ){ 32 Vが= VEC [U]は[I]。 33 であれば([V] == DFN - 1 ){ 34 tarjan(V)。 35 低[U] = 分(低[U]、[V]低いです)。 36 } 37 他 もし(inStack [V]){ 38 低[U] = 分(低[U]、[V] DFN)。 39 } 40 } 41 であれば(DFN [U] == 低[U]){ 42 CNT ++ 。 43 DO { 44 V =スタック[top-- ]。 45 inStack [V] = 偽。 46 } 、一方(U =!V)。 47 } 48 } 49 50 INT メイン(){ 51 のint N、M。 52 一方(scanf関数(" %dの%のD "、&N、&M)、N || M){ 53 のinit(); 54 一方(M-- ){ 55 int型A、B。 56 のscanf(" %D%dの"、&、&B)。 57 VEC [A] .push_back(B)。 58 } 59 のための(int型 i = 1 ; iが<= N; iが++ ){ 60の 場合(DFN [I] == - 1 ) 61 tarjan(I)。 62 } 63 であれば(CNT == 1)のprintf(" はい\ N " ); 64 他の printf関数(" ノー\ nを" ); 65 } 66 }