km算法

例题;

http://acm.hdu.edu.cn/showproblem.php?pid=2255

中文题目。。。

代码:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stdio.h>
using namespace std;
# define maxn  500+10
# define inf 0x3f3f3f3f
int a[maxn][maxn];
int nx[maxn],ny[maxn];
int visx[maxn],visy[maxn];
int net[maxn];
int slack[maxn];
int n;
void init1()
{
    memset(net,0,sizeof(net));
    memset(nx,0,sizeof(nx));
    memset(ny,0,sizeof(ny));
}
void init2()
{
    memset(visx,0,sizeof(visx));
    memset(visy,0,sizeof(visy));
}
bool Find(int t)
{
    visx[t]=1;
    for(int i=1; i<=n; i++)
    {
        if(nx[t]+ny[i]-a[t][i]==0)
        {
            if(visy[i])continue;
            visy[i]=1;
            if(net[i]==0||Find(net[i]))
            {
                net[i]=t;
                return true;
            }
        }
        else
        slack[i]=min(slack[i],nx[t]+ny[i]-a[t][i]);
    }
    return false;
}
int km()
{
    for(int i=1; i<=n; i++)
    {
        memset(slack,inf,sizeof(slack));
        while(1)
        {
            init2();
            if(Find(i))break;
            int minn=inf;
            for(int i=1; i<=n; i++)
            {
                if(!visy[i])minn=min(minn,slack[i]);
            }
            for(int i=1; i<=n; i++)
            {
                if(visx[i])nx[i]-=minn;
            }
            for(int i=1; i<=n; i++)
            {
                if(visy[i])ny[i]+=minn;
            }
        }
    }
    int sum=0;
    for(int i=1; i<=n; i++)
    {
        sum+=a[net[i]][i];
    }
    return sum;
}
int main()
{
    while(~scanf("%d",&n))
    {
        init1();
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=n; j++)
            {
                scanf("%d",&a[i][j]);
                nx[i]=max(nx[i],a[i][j]);
            }
        }
        int t=km();
        printf("%d\n",t);
    }
    return 0;
}
 

 

posted @ 2018-07-23 16:21  Let_Life_Stop  阅读(197)  评论(0编辑  收藏  举报