トピックへのリンク:https://www.luogu.org/problem/P2341
質問の意味:BのようなAは、BはC、その後のようなCのように、誰も自分を好きでなければなりませんでしたどのように多くの人々のように所有者に問い合わせます
入力形式:N、Mは番号と次の2行の間の関係のような人々の総数各m番号のようなBの、Bの代表であります
分析:入力フォーマットが容易図で行う、Aが限りの強連結成分が存在するように等BのBのアップ、点が互いに到達可能なすべての強連結成分を表し、図のトピックに起こる変換することができます。強連結成分を点までBは、すべての点Bまで、我々は、還元ポイントに続く各強連結成分内の点の数を計算して記録する強連結成分のTarjanのアルゴリズムを利用しました。私たちが観察し続けてポイントを縮小した後、我々はポイント0度が唯一のものであるならば、それは連結グラフ、およびこれまでの他のすべての点でなければならない、そしてそのポイントは、その後の点(凝縮点の後に、他のポイントに達することができなかったことがわかりました強連結成分)の数のポイントが答えであり、0度のうち2つの以上の点が、この数字は連結グラフでない場合、答えは0です。
直接圧縮セットポイントアルゴリズムTarjanテンプレート、およびレコードへの各ポイント度の最後に記録数。
#include <ビット/ STDC ++ H.> の#define MAXN 10001 使用して 名前空間STD; ベクター < INT > G [MAXN]; スタック < INT > S; int型N-、M; INT DFN [MAXN]、VIS [MAXN]、低[ MAXN]、色[MAXN]、NUM [MAXN]、Colornum = 0 、RES [MAXN]、CNT; // 各色記録NUMのポイント数、RESの各点記録 ボイドペイント(int型X) { s.pop(); 色[X] = Colornum; NUM [Colornum] ++ ; VIS [X]は = falseに; } ボイド tarjan(INT X) { [X] DFN =低[X] = ++ CNT。 s.push(X)。 VIS [X] = 真。 以下のために(int型 i = 0 ; iは、Gを<[X] .size(); iは++ ) { int型 Q = G [X] [I]; もし(!DFN [Q]) { tarjan(Q)。 低[X] = 分(低[x]は、低[Q])。 } そう であれば(VIS [Q])低[X] = 分(低[x]は、DFN [Q])。 } であれば(低[X] == DFN [X]) { colornum ++ ; 一方、(!s.top()= X) { int型 T = s.top()。 塗料(T)。 } 塗料(X)。 } } int型のmain() { CIN >> N >> M。 以下のために(int型 I = 1 ; I <= M; iは++ ) { int型Uを、V。 CIN >> U >> V; G [U] .push_back(V)。 } のための(int型 i = 1 ; iが<= N; iが++ ) { もし(!DFN [i])とtarjan(I); } INT ANS = 0 。 以下のために(int型 i = 1 ; iが<= N; iは++ ) { ための(int型 J = 0 ; J <G [I] .size(); J ++ ){ もし!(色[I] = カラー[G [i]が[J]]){ RES [色[I]] ++ ; } } } のための(int型 I = 1 ; I <= colornum; iが++ ){ 場合(ANS == 0 && RES [I] == 0){ ANS = NUM [I]。 } そう であれば(RES [I] == 0 ){ ANS = 0。破ります; } } COUT << ANS << ENDL。 リターン 0 ; }