일반적인 그래프 최대 매칭 (템플릿)

제목 : HTTP : //uoj.ac/problem/79

아무것도 이분 그래프에서 단 다른 말 없습니다

알고리즘 : 나무와 꽃 알고리즘

#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 ;
}
코드보기

 

추천

출처www.cnblogs.com/starve/p/11716598.html