(バーの時に冬のトレーニングキャンプに滞在する可能性が高い、結果は私が今までつぶやくでした...
見ることは非常に簡単ですTarjanシンプルなアプリケーション、。
図の星の牛1つだけのコンポーネントのは、強力なリンク0です。
強力なリンク0の構成要素のうちの2つ以上が存在する場合、これらは0間の「愛」強連結成分の度合いを渡すことはできませんので、その後、何のスターの牛は、ありません
だから、最終的な答えはで牛ユニコム強いコンポーネントの数です!
書式#include <cstdioを>
する#include <アルゴリズム>
書式#include <キュー>
の#include <スタック>
に#define LL長い長い
使って 名前空間はstdを、
インラインLLリード()
{
LL和 = 0、P = 1 。
チャー CH = GETCHAR()。
一方、(CH < ' 0 ' || CH> ' 9 ' )
{
場合(CH == ' - ' )
のp = - 1 。
CH =getchar関数();
}
一方、(CH> = ' 0 ' && CH <= ' 9 ' )
{
(SUM * = 10)+ = CH - ' 0 ' 。
CH = GETCHAR()。
}
リターン合計* P;
}
CONST INT MAXN = 10005、MAXM = 50005 。
構造体のエッジ
{
int型NXT、であり;
} E [MAXM]。
INTのN、M、CNT、TOT、NCNT。
int型DFN [MAXN]、低[MAXN]、MRK [MAXN]、ID [MAXN]、デュ[MAXN]、ヘッド[MAXN]。
BOOL VIS [MAXN]。
スタック < 整数 > Q;
ボイド追加(INT A、INT B)
{
E [ ++ CNT] .TO = B。
E [CNT] .nxt = ヘッド[A]。
ヘッド[A] = CNT。
}
ボイド tarjan(INT X)
{
[X] DFN =低[X] = ++ TOT。
q.push(X)。
VIS [X] = 真。
用(int型 I; I = I =ヘッド[X]E [I] .nxt)
{
int型、V = E [I] .TO。
もし(!DFN [V])
{
tarjan(V)。
低[X] = 分(低[x]は、低[V])。
}
そう であれば(VIS [V])
低[X] = 分(低[X]、[V] DFN)。
}
INT K。
もし([X] == DFN 低い[X])
{
NCNT ++ 。
実行
{
K = q.topを();
q.pop();
VIS [K] = 偽;
ID [K] = NCNT。
MRK [NCNT] ++ ;
} 一方(X =!K)。
}
}
int型のmain()
{
N)=(読み取り、M = (読み取り)
用(int型 I = 1 ; I <= M; iが++ )
{
int型 A =読み取る()、= B )(読み取ります。
追加(A、B)。
}
のために(int型 I = 1は iが++; iがn = < )
であれば(!DFN [i])と
tarjan(I)。
にとって(int型 i = 1 ; iは= <N; I ++ )
のための(INT J =頭部[I]; J; J = E [J] .nxt)
{
int型、V = E [J] .TO。
もし(ID [i]を=!ID [V])
デュ[ID [I]] ++ ;
}
INT ANS = 0 。
以下のために(int型 I = 1 ; I <= NCNT; iは++ )
場合(!デュ[I])
{
場合(ANS)
{
のprintf(" 0 \ n ");
リターン 0 ;
}
ANS = I。
}
のprintf(" %d個の\ n " 、MRK [ANS])。
リターン 0 ;
}