KM算法O(n^3)模板 hdu2255

来源:互联网 发布:怎么把mac文件拷到硬盘 编辑:程序博客网 时间:2024/05/20 13:36
#include<iostream>using namespace std;const int maxn=300+5;const int inf=(1<<30);int w[maxn][maxn];int lx[maxn],ly[maxn];int s[maxn],t[maxn];int slack[maxn];int match[maxn];int n;bool find(int i){    s[i]=true;    for(int j=1;j<=n;j++)    {        if(t[j]) continue;        int tmp=lx[i]+ly[j]-w[i][j];        if(tmp==0)        {            t[j]=true;            if(match[j]==-1||find(match[j]))            {                match[j]=i;                return true;            }        }        else if(slack[j]>tmp) slack[j]=tmp;    }    return false;}void update(){    int d=inf;    for(int i=1;i<=n;i++)        if(!t[i]&&d>slack[i]) d=slack[i];    for(int i=1;i<=n;i++)        if(s[i]) lx[i]-=d;    for(int i=1;i<=n;i++){        if(t[i]) ly[i]+=d;        else slack[i]-=d;    }}void KM(){    memset(match,-1,sizeof(match));    memset(ly,0,sizeof(ly));    for(int i=1;i<=n;i++)    {        lx[i]=-inf;        for(int j=1;j<=n;j++)            if(w[i][j]>lx[i]) lx[i]=w[i][j];    }    for(int i=1;i<=n;i++)    {        for(int j=1;j<=n;j++) slack[j]=inf;        for(;;)        {            memset(s,0,sizeof(s));            memset(t,0,sizeof(t));            if(find(i)) break;else update();        }    }}int main(){    while(~scanf("%d",&n))    {        memset(w,0,sizeof(w));        for(int i=1;i<=n;i++)            for(int j=1;j<=n;j++) scanf("%d",&w[i][j]);        KM();        int ans=0;        for(int i=1;i<=n;i++) if(match[i]!=-1) ans+=w[match[i]][i];        printf("%d\n",ans);    }    return 0;}

0 0
原创粉丝点击