KM模版

假定有一个完全二分图G,每条边有一个权值(可以是负数),如何求出权值和最大的完美匹配?

KM算法也称匈牙利算法

int Left[MAXN];
int w[MAXN][MAXN];
int Lx[MAXN],Ly[MAXN];
bool S[MAXN],T[MAXN];
int N;
bool match(int i)
{
    S[i]=true;
    for(int j=1;j<=N;j++)if(Lx[i]+Ly[j]==w[i][j]&&!T[j])
    {
        T[j]=true;
        if(Left[j]==0||match(Left[j]))
        {
            Left[j]=i;
            return true;
        }
    }
    return false;
}
void update(){
    int a=INF;
    for(int i=1;i<=N;i++)if(S[i])
        for(int j=1;j<=N;j++)if(!T[j])
            a=min(a,Lx[i]+Ly[j]-w[i][j]);
    for(int i=1;i<=N;i++){
        if(S[i])Lx[i]-=a;
        if(T[i])Ly[i]+=a;
    }
}
void KM()
{
    for(int i=1;i<=N;i++){
        Left[i]=Lx[i]=Ly[i]=0;
        for(int j=1;j<=N;j++)
        {
            Lx[i]=max(Lx[i],w[i][j]);
        }
    }
    for(int i=1;i<=N;i++){
        for(;;){
            CL(S,0);
            CL(T,0);
            if(match(i))break;
            else update();
        }
    }
}
原文地址:https://www.cnblogs.com/arbitrary/p/2936013.html