您的位置:首页 > 其它

hdu2255 KM模板

2015-10-09 19:02 246 查看
#include <cstdio>
#include <cstring>
#include <algorithm>

const int MAXN = 300+10;
const int INF = 0x3f3f3f3f;

int n, nx, ny;
int lx[MAXN], ly[MAXN];
// adjacent matrix to store graph
int ma[MAXN][MAXN];
int slack[MAXN];
int match[MAXN];
bool visx[MAXN], visy[MAXN];

bool findPath(int x)
{
visx[x] = true;
for (int y = 1; y <= ny; ++y) {
if (true == visy[y]) {
continue;
}
int tmp = lx[x] + ly[y] - ma[x][y];
if (0 == tmp) {
visy[y] = true;
if (-1 == match[y] || true == findPath(match[y])) {
match[y] = x;
return true;
}
}

if (slack[y] > tmp) {
slack[y] = tmp;
}

}
return false;
}

int km()
{
nx = ny = n;

// init...
memset(match, -1, sizeof match);
memset(ly, 0, sizeof ly);
for (int x = 1; x <= nx; ++x) {
lx[x] = -INF;
for (int y = 1; y <= ny; ++y) {
lx[x] = std::max(lx[x], ma[x][y]);
}
}

for (int x = 1; x <= nx; ++x) {
for (int y = 1; y <= ny; ++y) {
slack[y] = INF;
}
while (true) {
memset(visx, false, sizeof visx);
memset(visy, false, sizeof visy);
if (true == findPath(x)) {
break;
}
int min_d = INF;
for (int y = 1; y <= ny; ++y) {
if (false == visy[y] && min_d > slack[y]) {
min_d = slack[y];
}
}
for (int x = 1; x <= nx; ++x) {
if (true == visx[x]) {
lx[x] -= min_d;
}
}
for (int y = 1; y <= ny; ++y) {
if (true == visy[y]) {
ly[y] += min_d;
}
else {
slack[y] -= min_d;
}
}

}
}
int res = 0;
for (int y = 1; y <= ny; ++y) {
if (-1 != match[y]) {
res += ma[match[y]][y];
}
}
return res;
}

int main()
{
while (~scanf("%d", &n)) {
// input graph
for (int i = 1;  i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
scanf("%d", &ma[i][j]);
}
}
printf("%d\n", km());
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: