KM算法模板

来源:互联网 发布:安卓手机应用 知乎 编辑:程序博客网 时间:2024/06/16 07:51

贴一贴~~已通过

奔小康赚大钱

 HDU - 2255

#include<iostream>#include<stdio.h>#include<queue>#include<algorithm>#include<string.h>#define MX 310#define INF 0x3f3f3f3f#define mem(x,y) memset(x,y,sizeof(x))#define FIN freopen("input.txt","r",stdin)using namespace std;
int n;int G[MX][MX],nx,ny;int lx[MX],ly[MX],match[MX],slack[MX];bool visx[MX],visy[MX];bool KM_dfs(int u){    visx[u]=1;    for(int i=1; i<=nx; i++)    {        if(lx[u]+ly[i]==G[u][i]&&!visy[i])        {            visy[i]=1;            if(match[i]==-1||KM_dfs(match[i]))            {                match[i]=u;                return 1;            }        }        else if(lx[u]+ly[i]!=G[u][i])slack[i]=min(slack[i],lx[u]+ly[i]-G[u][i]);    }    return 0;}void update(){    int d=INF;    for(int i=1; i<=ny; i++) if(!visy[i]) d=min(d,slack[i]);    for(int i=1; i<=nx; i++)if(visx[i]) lx[i]-=d;    for(int i=1; i<=ny; i++) if(visy[i]) ly[i]+=d;        else slack[i]-=d;}int KM(){    mem(ly,0);    mem(match,-1);    for(int i=1; i<=nx; i++)    {        lx[i]=-INF;        for(int j=1; j<=ny; j++)lx[i]=max(lx[i],G[i][j]);    }    for(int i=1; i<=nx; i++)    {        mem(slack,0x3f);        while(1)        {            mem(visx,0);            mem(visy,0);            if(KM_dfs(i)) break;            else update();        }    }    int ans=0;    for(int i=1; i<=ny; i++)  ans+=match[i]==-1?0:G[match[i]][i];    return ans;}int main(){    FIN;    while(~scanf("%d",&n))//    {        for(int i=1,x; i<=n; i++)            for(int j=1; j<=n; j++)            {                scanf("%d",&x);                G[i][j]=x;            }        nx=ny=n;        printf("%d\n",KM());    }    return 0;}


 

0 0
原创粉丝点击