hdu 2853 Assignment (KM算法)

来源:互联网 发布:mac怎么在pdf上写字 编辑:程序博客网 时间:2024/06/06 01:13

题目描述

传送门

题解

KM算法

代码

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#define N 320#define inf 1000000000using namespace std;int n,m,pdx[N],pdy[N],cx[N],cy[N],belong[N],slack[N],val[N][N];bool dfs(int x){    pdx[x]=1;    for (int i=1;i<=m;i++) {        if (pdy[i]) continue;        int gap=cx[x]+cy[i]-val[x][i];        if (!gap) {            pdy[i]=1;            if (!belong[i]||dfs(belong[i])) {                belong[i]=x;                return true;            }        }else slack[i]=min(gap,slack[i]);    }    return false;}int km(){    memset(belong,0,sizeof(belong));    memset(cy,0,sizeof(cy));    for (int i=1;i<=n;i++) {        cx[i]=val[i][1];        for (int j=2;j<=m;j++) cx[i]=max(cx[i],val[i][j]);    }    for (int i=1;i<=n;i++) {        for (int j=1;j<=m;j++) slack[j]=inf;        while (true) {            memset(pdx,0,sizeof(pdx));            memset(pdy,0,sizeof(pdy));            if (dfs(i)) break;            int d=inf;            for (int j=1;j<=m;j++)             if (!pdy[j]) d=min(d,slack[j]);            for (int j=1;j<=n;j++)              if (pdx[j]) cx[j]-=d;            for (int j=1;j<=m;j++)             if (pdy[j]) cy[j]+=d;             else slack[j]-=d;        }    }    int ans=0;    for (int i=1;i<=m;i++) ans+=val[belong[i]][i];    return ans;}int main(){    freopen("a.in","r",stdin);    while (scanf("%d%d",&n,&m)!=EOF) {        for (int i=1;i<=n;i++)         for (int j=1;j<=m;j++)           scanf("%d",&val[i][j]),val[i][j]*=10000;        int sum=0;        for (int i=1;i<=n;i++) {            int x; scanf("%d",&x);            sum+=val[i][x]; val[i][x]++;         }        sum/=10000;        int ans=km();        printf("%d %d\n",n-ans%10000,ans/10000-sum);    } }
0 0
原创粉丝点击