그래프를 들면 G ( V , E ) 하는 일치,M은 튜플 ( U , V ) 세트 이들 상기 U , V ∈ V,(U, V) ∈E하고,M이 존재하지 않는 중복 지점.
시 | 남성 | 큰 시간, 우리가 전화를 M을 에 G의 최대 일치.
경우 G는 최대 매칭 고전 헝가리어 알고리즘 또는 네트워크 흐름 알고리즘을 사용하여 해결 될 수있다 된 그래프이다. 그러나,G는 직접 증강 일반보기가 가능하게하고,이 시간 우리는 일치하는 작업을 완료하는 나무와 꽃 알고리즘을 사용합니다.
1 #INCLUDE <cstdio> 2 #INCLUDE <cctype> 3 #INCLUDE <CString을> 4 #INCLUDE <알고리즘> 5 이용 공간을 성병; 6 INT의 판독 () { 7 INT X = 0 , F = 1 ; 8 문자 C = getchar가 (); 9 대 (; isdigit에 (c) C = getchar가 (!)에서) 경우, (c == ' - ' ) F = - 1 ; 10 대 (; isdigit에 (c) C = getchar가 ()) X = X * 10 + C- ' 0 ' ; 11 창 X * F; 12 } 13 CONST INT maxn = 505 ; 14 CONST INT의 MAXM = maxn maxn * * 2 ; 15 INT N, m, 가야가 [MAXM, QL은 QR은 [maxn] 미리 팀 = 0 ; 16 구조체 에지 { 17 INT의 V, NXT; 18 } E [MAXM]; 19 INT H [maxn, TOT = 0 ; 20 INT 매치 [maxn], F [maxn, TP [maxn, TIC [maxn]; 21 INT 찾기 ( INT X) { 22 반환F [X] == X F [X] : F [X] =? 발견 (F [X]); 23 } 24 무효 추가 ( int로 , U를 INT V)를 { 25 E [++ TOT] = (에지) {V, H [U]}; 26 H [U] = TOT; 27 } 28 INT의 LCA ( INT의 X, INT Y) { 29 대 (++ 팀; 스왑 (X, Y)) 의 경우 (X) { 30 X = 발견 (X); 31 일 경우 (TIC [X] == 팀) 창 X; 다른 TIC [X] = 팀, X = 프리 [매치 [X]; 32 } 33 } 34 무효 수축 ( INT의 X, INT Y, INT의 P) { 35 동안 ((x)를 발견! = P) { 36 미리는 [X]는 = Y는, Y가 = 일치 [X]; 37 의 경우 (TP [Y] == 2 ) TP [Y] = 1 , 케 [++ QR = Y; 38 의 경우 F ((x)는 X == 찾기)을 [X] = P; 39 의 경우 (찾기 (Y) == Y) [Y] F = P; 40 X = 프리 [Y]; 41 } 42 } 43 부울 8월 ( INT S) { 44 대( INT가 나는 = 1 ; I <= N; ++ I) F [I] = I; 45 memset 함수 (TP, 0 , sizeof 연산자 TP)가 memset (미리 0 , 는 sizeof 사전); 46 TP [케 [QL = QR = 1 ] = S = 1 ; // 1 : A 형; 2 : B 형 (47) 의 INT t = 0 ; 48 동안 (QL <= QR) { (49) INT (X) = 케 [QL ++ ]; 50 대 ( 하는 int i가 H가 = [X], V = E [I] .V 내가, 내가 전자 = [I] .nxt, V = E [I] .V) { 51 하다면((V)를 찾아 찾아 == (X) || TP [V] == 2 ) 계속 ; (52) 만약 (! TP [V]) { 53 (TP)는 [V] = 2 , 미리 [V] = X; (54) 만약 (! 매치 [V]) { 55 대 ( INT 지금 = V, 마지막 TMP는, 지금, 지금 = 마지막) { 56 마지막 = 일치 [TMP가 = [전 이제]; (57) 검색 [현재] = TMP 경기 [TMP = 이제; 58 } 59 반환 참 ; 60 } 61 TP [매치 [V] = 1 , 케 [++ QR = 매치 [V]; 62 } 다른 경우 (TP [V] == 1 ) { 63 INT의 L = LCA (X, V); (64) 수축 (X, V, l); (65) 수축 (V, X, l); 66 } 67 } 68 } 69 반환 거짓 ; 70 } 71 INT 의 main () { 72 ONLINE_JUDGE #ifndef 73 freopen을 ( " test.in " , "R " 표준 입력) 74 개 freopen을 ( " my.out " , " w " , 표준 출력) 75 #endif 다음 76 N = (판독), m = ) (읽기, 77 대 ( INT는 난 = 1 I <= m; ; ++ I) { 78 INT (X) = (판독), Y는 = () 읽기, 79 추가 (x, y)에, 추가 (Y, X) (80) } (81) INT ANS = 0 , 82 대 ( INT I = 1 ; I <= N; ++ I) + = ANS (매치 [I] &&! 8월 (I)); 83 의 printf ( " 가 % d \ n " , ANS); 84 대 ( INT 나 = 1 ; i가 <= N; ++ I)의 printf ( " %의 D " 경기 [I]); 85 풋 ( "" ); 86 반환 0 ; 87 }
원본 제목은 UOJ79이다, ANS i 번째 개인의 배우자 예를 나타내는 경기의 최대 번호, 경기는 [I]입니다.