아이디어 : $ tarjan + DP $
제출 : 1
해결 방법 : 강하게 연결 구성 요소가 먼저 크기 $을 $해야합니다 반 연결 구성 요소의 반 연결 구성 요소의 크기와 형태를해야합니다, 우리는 축소 가리 킵니다.
이러한 방법으로, 우리는 DAG $은 (한 번 갈래면이 반 연결 구성 요소가 될 수 없습니다) 새로운 $에서 가장 긴 체인 중 하나에 해당를 찾고 싶어요.
이후 쓰기 $ DFS $, $ SZ [U]는 $ 것을 나타냅니다 점의 개수가 점하는 단계를 포함하는, $ MX는 [U] U $ $ $ 가장 긴 사슬 길이, $부터 발현 된 (환원 후) TOT [U] $는 방식을 나타냅니다.
그러나이 그림이 연결되지 않을 수 있습니다.
#INCLUDE <cstdio> #INCLUDE <iostream> #INCLUDE <지도> #DEFINE ULL 긴 부호 길이 #DEFINE가 긴 긴 것이다 #DEFINE의 R 레지스터 INT 사용 스페이스 성병; #DEFINE 일시 정지 (위한 (R 된 I = 1; i가 <= 10000000000; I ++)) #DEFINE freopen을 IN ( 'NOIPAK ++이다. ""R ", 표준 입력) #DEFINE 아웃 freopen을 ("나가자 밖으로 "," w ", 표준 출력) 공간 FREAD { 정적 숯 B의 [ 1 << 15 ] * S = B * D = B; #ifndef JACK #DEFINE의 getchar가 () (S == && D (D = (S = B) + FREAD (B, 1,1- << 15 표준 입력) 인라인 INT의 g () { R의 RET = 0 , FIX = 1 ; 등록 숯 CH 단계; 동안 (! isdigit에 (CH = getchar가 ())) 수정 = 채널 == ' - ' - 1 : 수정; 경우 (CH2 == EOF) 복귀 EOF; DO RET RET = * 10 + (CH ^ 48 ); 반면 (isdigit에 (CH = getchar가 ())); 반환 RET의 *의 수정; } 인라인 부울 IsEmpty 함수 ( CONST CHAR & CH) { 창 (CH2 <= 36 || CH> = 127)} 인라인 공극 GS ( 숯 *의 S) { 등록 숯 CH 단계; 반면 (IsEmpty 함수 (CH = getchar가 ())); 할 *의 ++ = 채널을; 반면 (IsEmpty 함수 (CH2 =! getchar가 ())); } } 사용 FREAD :: g을; 사용 FREAD :: GS를; 공간 Luitaryi { CONST의 INT의 N = 100,010 , M = 1,000,010 ; 지도 <쌍 < INT , INT > BOOL > MP; int로 N, m, 개조; INTVR [M << 1 ], NXT [M << 1 ], 전나무 [M << 1 ] 카본 나노 튜브; 인라인 공극 추가 ( INT U, INT V) {의 VR [++ CNT가] = V, NXT [CNT] = 전나무 [U], 전나무 [U] = CNT} INT의 절 [M << 1 ], NN [M << 1 ], FF [M << 1 ], CT; 인라인 공극 adde ( INT U, INT V) {VV의 [++ CT] = V, NN [CT] = FF를 [U], FF [U]는 = CT} INT DFN [N], 로우 [N], (C) [N], STK [N], SZ [N], T [N], NUM, 참조 가기; 불리언 힘 [N]; 인라인 공극 tarjan ( INT U) { DFN [U]낮은 = [U] = NUM ++; STK [++ 최고] 힘을가 U = U = 참 ; 위한 (R = I 전나무 [U] I, I = NXT [I]) {R = 브이를 VR [I]; 만약 (! {[V] DFN) tarjan (V); 낮은 [U] = 분 (저 [U], 로우 [V]); } 다른 경우 (힘 [V]) 로우 [U] = 분 (저 [U] DFN [V]); } 경우 (DFN [U] == 낮은 [U]) { ++ CC; R의 tmp; 이렇게 , TMP = STK [정상] - 상단, [TMP] = CC C ++ SZ [CC], 마주 [TMP] = 거짓 ; 반면 (TMP =! U)를; } } INT anss, ANS, MX [N], TOT [N]; 인라인보이드 DFS는 ( int로 {U)의 힘은 [U]가 = 참 ; MX [U] = SZ [U], TOT [U] = 1 ; 위한 (R = I의 FF [U] I, I = NN [I]) {R = 브이의 절 [I]; 만약 (! 힘 [V]) DFS (V); 경우 (SZ [U] + MX [V]> MX [U]) { MX [U] = SZ [U] + MX [V]; TOT [U] = 된 TOT [V]; } 다른 경우 (SZ [U] + MX [V] == MX [U]) TOT [U] = (TOT [U] + TOT [V]) % 개조; ANS} = 최대 (MX [U], ANS); } 인라인 무효주 () { N = g (), m = g (), 모드 = g (); 위한 (R 난 = 1 , U는 V, I <= m; I ++) U = g (), V = g ()에 추가 (U, V); 위한 (R 난 = 1 ; 나는 <= N; ++ ⅰ) 만약 (! tarjan (I) [I] DFN); 위한 (R U = 1 , U <= N; ++ U) 에 대한 (R = I 전나무 [U] I, I = NXT [I]) {R = 브이를 VR [I]; 경우 (c [U]! =의 C [V] && mp.find (make_pair (c [U], C [V])) == mp.end ()) ++ t [C [V], adde (c [U], C는 [V]), MP [make_pair (c [U]는, C는 [V])] = 참 ; } 에 대한 (R은 I = 1 ; 나는 = CC를 <; I ++) 경우 (t [I] ||!의!힘 [I]) DFS (I); 위한 (R I = 1 ; 나는 = CC를 <; I ++) 경우 (MX [I] == ANS) anss = (TOT anss + [I]) % 개조; 의 printf ( " 가 % d \ n을가 % d \ 없음 " , ANS, anss); } } 주 () {서명 Luitaryi :: 주 (); 반환 0 ; }
2019년 7월 22일