代码:
int main()
{
while(~scanf("%d", &n))
{
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
scanf("%d", &mp[i][j]);
int ans =KM();
printf("%d\n", ans);
}
return 0;
}
int KM()
{
int i, j;
memset(ly, 0, sizeof(ly));
memset(match, -1, sizeof(match));
for(i = 1; i <= n; i++)
{
lx[i] = 0;
for(j = 1; j <= n; j++)
lx[i] = max(lx[i], mp[i][j]);
}
for(i = 1; i <= n; i++)
{
while(1)
{
memset(vx, 0, sizeof(vx));
memset(vy, 0, sizeof(vy));
d = inf;
if(hungary(i)) break;
for(j = 1; j <= n; j++)
{
if(vx[j]) lx[j] -= d;
if(vy[j]) ly[j] += d;
}
}
}
int ans = 0;
for(i = 1; i <= n; i++)
{
ans += mp[match[i]][i];
}
return ans;
}
int hungary(int u)
{
vx[u] = 1;
for(int i = 1; i <= n; i++)
{
if(vy[i]) continue;
if(lx[u] + ly[i] == mp[u][i])
{
vy[i] = 1;
if(match[i] == -1 || hungary(match[i]))
{
match[i] = u;
return 1;
}
}
else d = min(d, lx[u] + ly[i] - mp[u][i]);
}
return 0;
}