二分图(Hopcroft-Carp算法)

二分图(Hopcroft-Carp算法)

 下面代码将上面的代码的邻接矩阵改成了vector存图。

顶点编号 u= 1~uN,v=uN+1~uN+vN,加边的时候加u到v的单向边就可以了,因此建图前要将原图分为u和v两个子图。

vector<int> G[maxn];
int Mx[maxn],My[maxn],Nx,Ny;
int dx[maxn],dy[maxn],dis;
bool vis[maxn];

bool searchP()
{
    queue<int> q;
    dis=INF;
    memset(dx,-1,sizeof(dx));
    memset(dy,-1,sizeof(dy));
    for(int i=0;i<Nx;i++){
        if(Mx[i]==-1){
            q.push(i);
            dx[i]=0;
        }
    }
    while(!q.empty()){
        int u=q.front();
        q.pop();
        if(dx[u]>dis) break;
        for(int i=0;i<G[u].size();i++){
            int v=G[u][i];
            if(dy[v]==-1){
                dy[v]=dx[u]+1;
                if(My[v]==-1) dis=dy[v];
                else{
                    dx[My[v]]=dy[v]+1;
                    q.push(My[v]);
                }
            }
        }
    }
    return dis!=INF;
}

bool dfs(int u)
{
    for(int i=0;i<G[u].size();i++){
        int v=G[u][i];
        if(!vis[v]&&dy[v]==dx[u]+1){
            vis[v]=1;
            if(My[v]!=-1&&dy[v]==dis) continue;
            if(My[v]==-1||dfs(My[v])){
                My[v]=u;
                Mx[u]=v;
                return true;
            }
        }
    }
    return false;
}

int MaxMatch()
{
    int res=0;
    memset(Mx,-1,sizeof(Mx));
    memset(My,-1,sizeof(My));
    while(searchP()){
        memset(vis,0,sizeof(vis));
        for(int i=0;i<Nx;i++){
            if(Mx[i]==-1&&dfs(i)) res++;
        }
    }
    return res;
}
View Code
没有AC不了的题,只有不努力的ACMER!
原文地址:https://www.cnblogs.com/--560/p/4544978.html