#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int M = 305;
const int MAX = 99999999;
int w[M][M];
int a[M], b[M];
int n, nx, ny;
int link[M];
int vistx[M];
int visty[M];
int sleck[M];
int ans;
int dfs(int x)
{
vistx[x] = 1;
for(int i = 1; i <= ny; i++)
{
if(visty[i])
continue;
int t = a[x] + b[i] - w[x][i];
if(t == 0)
{
visty[i] = 1;
if(!link[i] || dfs(link[i]))
{
link[i] = x;
return 1;
}
}
else if(sleck[i] > t)
{
sleck[i] = t;
}
}
return 0;
}
int KM()
{
memset(link, 0, sizeof(link));
memset(b, 0, sizeof(b));
memset(a, 0, sizeof(a));
for (int i = 1;i <= nx;i ++) {
a[i] = -MAX;//lx初始化为与它关联边中最大的
for (int j = 1;j <= ny;j ++)
if (w[i][j] > a[i])
a[i] = w[i][j];
}
for(int k = 1; k <= nx; k++)
{
for(int i = 1; i <= n; i++)
sleck[i] = MAX;
// printf("k = %d ", k);
while(1)
{
memset(vistx, 0, sizeof(vistx));
memset(visty, 0, sizeof(visty));
if(dfs(k))
break;
int d = MAX;
for(int i = 1; i <= n; i++)
{
if(!visty[i] && d > sleck[i])
d = sleck[i];
}
for(int i = 1; i <= nx; i++)
if(vistx[i])
a[i] -= d;
for(int i = 1; i <= ny; i++)
if(visty[i])
b[i] += d;
else
sleck[i] -= d;
}
}
int res = 0;
for(int i = 1; i <= nx; i++) {
if(link[i])
res += w[link[i]][i];
}
return res;
}
int main()
{
while(scanf("%d", &n) != EOF)
{
nx = ny = n;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
scanf("%d", &w[i][j]);
//printf("sfdsf\n");
ans = KM();
printf("%d\n", ans);
}
return 0;
}
hdu 2255 二分图的完备匹配
最新推荐文章于 2022-04-03 15:47:36 发布