例题;
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;
}