Maximum matching in general graphs (template)

Title: http: //uoj.ac/problem/79

Nothing to say, just different from the bipartite graph

Algorithms: algorithms with trees and flowers

#include<bits/stdc++.h>
using namespace std;
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=b;i>=a;i--)
const int N=550;
int n,head[N],pre[N],match[N],f[N],col[N],cmp[N],tot;
const int M=5e5+5;
struct node{
    int u,v,nextt;
}e[M];
int num;
void addedge(int u,int v){
    e[num].v=v;
    e[num].nextt=head[u];
    head[u]++ NUM = ; 
} 
int Find ( int X) {
     return F [X] X X ==:? F [X] = Find (F [X]); 
} 
int lca ( int X, int Y) { // entire lca achieve more clever, because it is BFS, then the two points on the current depth must equal the odd ring, alternately looking lca violence can be. 
    TOT ++ ; 
    X = Find (X), Y = Find (Y);
     the while (! CMP [X] = TOT) { 
        CMP [X] = TOT; 
        X = Find (pre [match [X]]);
         IF (Y ) 
            the swap (X, Y); 
    } 
    return X; 
} 
Queue <int > que;
 void the make ( int X, int Y, int W) { // condensed ring (flowering) during 
    the while (! Find (X) = W) { 
        pre [X] = Y, Y = match [X]; // the X-is the original black spots, y is the original white point, the original pre turns into a double edge. 
        IF (COL [y] == 2 ) // if y is dyed black or white point 
            COL [y] = . 1 , que.push (y);
         IF (Find (X) == X) 
            F [X] = W ;
         IF (Find (Y) == Y) 
            F [Y] = W; 
        X =  pre [Y];
    }
    
}
int  solve(int st){
    while(!que.empty())
        que.pop();
    que.push(st);
    fo(i,1,n)
        f[i]=i,pre[i]=col[i]=0;
    col[st]=1;//1 is black 
    while(!que.empty()){
        int u=que.front();
        que.pop();
        for(int i=head[u];~i;i=e[i].nextt){
            int v=e[i].v;
            if(Find (V) == Find (U) || COL [V] == 2 )
                 Continue ; // If one had already reduced or even odd cycloalkyl ring is skipped 
            IF (! {COL [V]) 
                COL [V] = 2 , pre [V] = U;
                 IF {(match [V]!) // find augmenting path 
                    for ( int X = V, y; X; X = y) { // return the modified matching 
                        y = match [pre [X]]; 
                        match [X] = pre [X]; 
                        match [pre [X]] = X; 
                    } 
                    return  . 1 ; 
                }
                // otherwise it is added to the queue matching point 
                COL [match [V]] = . 1 ; 
                que.push (match [V]); 
            } 
            the else {
                 int the LCA = LCA (U, V); 
                the make (U, V, the LCA); 
                the make (V, U, the lCA); // above were modified to lca path and the path to v lca (the two halves) loop 
            } 
        } 
    } 
    return  0 ; 
} 
int main () {
     int m; 
    Memset (head, - . 1 , the sizeof (head) ); 
    Scanf ( " % D% D " , & n-, & m); 
    FO (I, . 1,m){
        int u,v;
        scanf("%d%d",&u,&v);
        addedge(u,v);
        addedge(v,u);
    }
    int ans=0;
    fo(i,1,n)
        if(!match[i])
            ans+=solve(i);
    printf("%d\n",ans);
    fo(i,1,n)
        printf("%d ",match[i]);
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/starve/p/11716598.html