問題の意味は:有向非巡回グラフが与えられると、各カウント数は、エッジのN個の点Mからの各点の始点に到達します。N、M <= 30000。
アイデア:最初のトポロジカル整列するので、確かにトポロジカル順序の前の前の間違いオーダーのトポロジーポイントの背面インチ 次いで、圧縮された状態では、後ろからバイナリビットセット、食事又はビットに変換され、番号1は、ポイント数の数が達成され得る表します。
書式#include <cstdioを> する#include <CStringの> の#include <アルゴリズム> 書式#include <ビットセット> の#include <cmath> の#include <キュー> の#include <iostreamの> 使用して 名前空間はstd; CONST INT MAXN = 30000 + 7 。 int型のヘッド[MAXN]、[MAXN]版。 INT 次に[MAXN]。 int型のTOT、CNT。 INTは[MAXN]、DEG [MAXN]。 INTのN、M。 ビット集合 <MAXN> [MAXN] C。 ボイド追加(int型のx、int型のY){ 版[ ++ TOT = Y、次に[TOT = 頭部[X]。 ヘッド[X] = TOT。 DEG [Y] ++ ; } ボイドtoposort(){ キュー < INT > Q。 以下のために(int型 I = 1 iが++; iが<= N ) であれば(DEG [I] == 0 )q.push(I)。 一方、(q.size()){ int型 X = )(q.front。 q.pop(); 【 ++ CNT] =のX。 用(int型 I; I = I =ヘッド[X]次の[I]){ int型、Y = 版[I]; DEG [Y] - 。 もし(DEG [Y] == 0 )q.push(Y)。 } } } ボイドは、(解決){ int型X、Y。 以下のために(int型 I = CNTを、I> = 1 ; i-- ){ X = [I]。 C [X] [X] = 1 。 用(INT ; J; J = J =頭部[X] 次に[J]){ int型、Y = 版[J]。 C [X] | =のC [Y]。 } } } int型のmain(){ int型のX、Y。 scanf関数(" %d個の%のD "、&N、&M)。 一方、(M-- ){ scanf関数(" %D%dの"、およびX&Y)。 (x、y)を加えます。 } toposort()。 解決する(); 以下のために(int型 i = 1 ; iが<= N; iが++ ) のprintf(" %Dを\ n " 、C [I] .count())。 リターン 0 ; }