제목 : HTTP : //uoj.ac/problem/79
아무것도 이분 그래프에서 단 다른 말 없습니다
알고리즘 : 나무와 꽃 알고리즘
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#INCLUDE <비트 / stdc ++ H.> 사용 스페이스 성병; #DEFINE (나는 A는, B)에 대한이 FO (INT 나 A =; 나는 <= B를 단계; 내가 ++) #DEFINE에 대한 FOD (I, a는 b) (I = 85의 B에 나타내는 int I> = A, 난 -) CONST의 INT의 N = 550 ; INT의 N, [N], COL 헤드 F [N], 전 [N] 경기 [N], [N], CMP [N], TOT; CONST의 INT의 M = 5e5 + (5) ; 구조체 노드 { int로 U, V, nextt; }여자 이름]; INT의 NUM; 보이드 addedge ( INT U, INT V) { 아웃 [여부] .V = V; E [NUM] .nextt = 헤드 [U]; 헤드 [U] = NUM ++ ; } INT의 발견 ( INT X) { 복귀 F [X] == X X : F [X] = 찾기 (F [X]); } INT LCA ( INT X, INT Y) { // 전체 LCA는 BFS 같이, 다음 홀수 링의 현재의 깊이에, 두 지점이 반드시 동일보다 미묘 달성이있다 교대 폭력 찾을 LCA. ++ TOT ; X = 찾기 (X), Y = (y)를 발견; 동안 CMP ([X]! = TOT) { CMP는 [X] = TOT 단계; X = 찾기 (프리 [매치 [X]); 경우 (Y) 스왑 (X, Y); } 반환 X를; } 큐 < INT > 케; 무효화 메이크 ( INT의 X는 int로 Y를 INT {W) // 축합 고리 중 (개화) 그동안 (! (X) = 찾기 W)을 { 예비 [X] = Y는 Y = 매치 [X]; // X 원래 검은 반점, y는 원래의 백색 포인트가되고, 일본어 사전 측 양방향된다. IF (COL [Y] == 2 ) // Y 염색 경우 블랙 또는 화이트 포인트 COL [Y] = 1. , que.push (Y), IF는 ((X) == 찾기 X)를 F [X] = w; 경우 (찾을 (Y) ==의 Y) F [Y] = w; X = 프리 [및]; } } INT (해결 int로 일을) { 동안 (! que.empty ()) que.pop (); (일) que.push; FO (I, 1 , N) F [내가] = 1은, 미리 [I] = (COL) [I] = 0 ; COL [ST는] = 1 ; // 1 검정 동안 (! {que.empty ()) INT U = que.front (); que.pop (); 대한 ( int로 ; ~ I I = I = 머리 [U] {E [I]를 .nextt) INT의 V = E [I] .V; IF는 (V (찾기) == 찾기 (U) || COL [V ] == 2 ) 계속 ; // 하나가 이미 감소했다 또는 홀수 사이클로 알킬 고리는 생략되는 경우 IF (! COL [V]) { COL은 [V] = 2 , 미리 [V] = U; IF는 {([V]가 일치!) // 경로 보강 찾기 위해 ( INT X = V, Y, X, X = Y) { // 수정 매칭을 리턴 = Y의 매치 [중고 [X]; 매치 [X] = 사전 [X]; 매치 [중고 [X] =의 X; } 반환 1 ; } // 그렇지 않으면, 그 매칭 점 엔큐 COL [매치 [V] =를 1. ; que.push (매치 [V]); } 또 { INT의 LCA = LCA (U, V); (U, V, LCA) 확인; 메이크 (V, U는 LCA는) // 상기 LCA 경로 및 V LCA 경로 (시클로 두 절반)로 수정 하였다 } } } 반환 0 ; } INT 의 main () { INT의 m; memset 함수 (머리 - 1 , 를 sizeof (헤드)); scanf와 ( " %의 D % d에 " , N, m); FO (I, 1 , m) { int로 U를 V; scanf와 ( " % d 개 %의 D ' , U, V); addedge (U, V); addedge (V, U); } INT 년 = 0 ; FO (I, 1 , n)의 경우 (! 매치 [I]) ANS + = (I) 해결; 의 printf ( " % D \ 없음 " , ANS); FO (I, 1 , N) 의 printf ( " %의 D " 경기 [I]); 반환 0 ; }