문제의 의미는 : 방향성 비순환 그래프의 특정 각 카운트 수는 에지의 N의 포인트 M에서 각각의 포인트의 시작 지점에 도달한다. N, M <= 30000.
아이디어 : 위상 정렬 첫째, 그래서 확실히 확실히 순서의 토폴로지 점 뒷면의 위상 순서의 맨 앞으로 앞에있다. 그런 상태를 압축 뒤에서 이진 비트 세트, 식사 또는 비트 변환하고, 숫자 1은 포인트 수의 개수가 달성 될 수 나타낸다.
#INCLUDE <cstdio> #INCLUDE <CString을> #INCLUDE <알고리즘> #INCLUDE <비트 세트> #INCLUDE <cmath> #INCLUDE <큐> #INCLUDE <iostream> 사용 스페이스 성병; CONST의 INT의 maxn = 30000 + 7 ; INT의 헤드 [maxn, 버전 [maxn]; INT 다음 [maxn]; INT의 어린 아이, CNT; INT는 [maxn] 내지 A [maxn]; INT의 N, m; 비트 세트 <maxn> [maxn] C; 보이드 추가 ( INT (X), INT Y) { 버전 [++ TOT = Y, 다음 [TOT] = 헤드 [X]; 헤드는 [X] = TOT 단계; ℃, [Y] ++ ; } 공극 toposort () { 큐 < INT > Q; 위한 ( int로 I = 1 난 ++; 나는 <= N ) 경우 (DEG [I] == 0 ) q.push (I); 반면 (q.size ()) { INT (X) = () q.front; q.pop (); A [ ++ CNT =의 X; 위한 ( int로 I = 헤드 [X] I, I = 다음 [I]) { INT Y = 버전 [I]; ℃, [Y] - ; 경우 (DEG [Y] == 0 ) q.push (Y); } } } 보이드가 ) (해결 { INT의 X, Y; 위한 ( int로 난 = CNT를, 난> = 1 , 난 - ) { 여기서 x = A [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 ; 나는 <= N; ++ i가 ) 의 printf ( " % D \ 없음 " 는 C [i]를 .count ()); 반환 0 ; }