KM模板

HDU 2255

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>

using namespace std;

#define N 306

int n,e[N][N];
int match[N],slack[N],ea[N],eb[N];
bool va[N],vb[N];

bool dfs(int u)
{
    va[u]=true;
    int gap;
    for(int i=1;i<=n;++i)
    {
        if(vb[i]) continue;
        gap=ea[u]+eb[i]-e[u][i];
        if(!gap) 
        {
            vb[i]=true;
            if(!match[i] || dfs(match[i])) 
            {
                match[i]=u;
                return true;
            }
        }
        else slack[i]=min(slack[i],gap);
    }
    return false;
}

void KM()
{
    memset(match,0,sizeof(match));
    memset(eb,0,sizeof(eb));
    for(int i=1;i<=n;++i)
    {
        ea[i]=0;
        for(int j=1;j<=n;++j)
            ea[i]=max(ea[i],e[i][j]);
    }
    int gap;
    for(int i=1;i<=n;++i)
    {
        fill(slack+1,slack+n+1,0x3f3f3f3f);
        while(1)
        {
            memset(va,false,sizeof(*va)*(n+1));
            memset(vb,false,sizeof(*vb)*(n+1));
            if(dfs(i)) break;
            gap=0x3f3f3f3f;
            for(int j=1;j<=n;++j) 
                if(!vb[j]) gap=min(gap,slack[j]);
            for(int j=1;j<=n;++j)
                if(va[j]) ea[j]-=gap;
            for(int j=1;j<=n;++j)
                if(vb[j]) eb[j]+=gap;
                else slack[j]-=gap; 
        }
    }
    int sum=0;
    for(int i=1;i<=n;++i) sum+=e[match[i]][i];
    printf("%d
",sum);
}

int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=1;i<=n;++i) 
            for(int j=1;j<=n;++j)
                scanf("%d",&e[i][j]);
        KM();
    }
    return 0;
} 
原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/11781342.html