HDU 2853 Assignment KM
http://acm.hdu.edu.cn/showproblem.php?pid=2853
题意:。。。暂略
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#define Max(a,b)a>b?a:b
#define Min(a,b)a<b?a:b
#define inf 99999999
#define nMAX 55
using namespace std;
int map[nMAX][nMAX],link[nMAX],slink[nMAX];
int lx[nMAX],ly[nMAX],n,m,cnt;
bool vx[nMAX],vy[nMAX];
bool dfs(int x)
{
int j;
vx[x]=1;
for(j=1;j<=m;j++)
{
if(!vy[j]&&map[x][j]==lx[x]+ly[j])//
{
vy[j]=1;
if(!link[j]||dfs(link[j]))
{
link[j]=x;
return 1;
}
}
}
return 0;
}
int KM()
{
int i,j,k;
for(i=1;i<=n;i++)
{
lx[i]=-inf;
for(j=1;j<=m;j++)
lx[i]=Max(lx[i],map[i][j]);
}
memset(ly,0,sizeof(ly));
memset(link,0,sizeof(link));
for(i=1;i<=n;i++)
{
while(1)
{
memset(vx,0,sizeof(vx));//失败 失败 !!
memset(vy,0,sizeof(vy));
if(dfs(i))break;
int MIN=inf;
for(j=1;j<=n;j++)
if(vx[j])
for(k=1;k<=m;k++)
if(!vy[k])
MIN=Min(MIN,lx[j]+ly[k]-map[j][k]);
for(j=1;j<=n;j++)if(vx[j])lx[j]-=MIN;
for(j=1;j<=m;j++)if(vy[j])ly[j]+=MIN;
}
}
int ans=0;
cnt=0;
for(j=1;j<=m;j++)
{
if(link[j])
{
if(slink[j]!=link[j])
cnt++;
ans+=map[link[j]][j];
}
}
return ans;
}
int main()
{
int i,j,k;
while(~scanf("%d%d",&n,&m))
{
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
scanf("%d",&k);
map[i][j]=k*100;
}
memset(slink,-1,sizeof(slink));//!!!
int pre=0;
for(i=1;i<=n;i++)//!!!
{
scanf("%d",&j);
slink[j]=i;
map[i][j]+=1;
pre+=map[i][j];
}
int ans=KM();
printf("%d %d\n",cnt,ans/100-pre/100);
}
return 0;
}

浙公网安备 33010602011771号