UVA 11383 Golden Tiger Claw 题解

Posted youxam

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA 11383 Golden Tiger Claw 题解相关的知识,希望对你有一定的参考价值。

-->

题解

其实就是一个KM的板子

KM算法在进行中, 需要满足两个点的顶标值之和大于等于两点之间的边权, 所以进行一次KM即可.

KM之后, 顶标之和就是最小的。因为如果不是最小的,就能通过修改顶标值来使某对顶点的顶标值满足(wx[i]+ly[j]==w[i][j]),这样相等子图中又会多一条边,但此时已全部匹配,所以是最小的。

代码

#include <algorithm>
#include <cstdio>
#include <cstring>
#define N 510
using namespace std;
const int inf = 1 << 30;
int s[N][N], lx[N], ly[N], match[N], slack[N], n;
bool vx[N], vy[N];
bool dfs(int u) {
    vx[u] = 1;
    for (int i = 1; i <= n; i++) {
        if (!vy[i]) {
            int t = lx[u] + ly[i] - s[u][i];
            if (t == 0) {
                vy[i] = 1;
                if (match[i] == -1 || dfs(mat[i])) {
                    match[i] = u;
                    return 1;
                }
            } else
                slack[i] = min(slack[i], t);
        }
    }
    return 0;
}
void KM() {
    memset(match, -1, sizeof(match));
    memset(ly, 0, sizeof(ly));
    for (int i = 1; i <= n; i++) {
        lx[i] = -inf;
        for (int j = 1; j <= n; j++) lx[i] = max(lx[i], s[i][j]);
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) slack[j] = inf;
        while (1) {
            memset(vx, 0, sizeof(vx));
            memset(vy, 0, sizeof(vy));
            if (dfs(i)) break;
            int d = inf;
            for (int j = 1; j <= n; j++)
                if (!vy[j]) d = min(d, slack[j]);
            for (int j = 1; j <= n; j++)
                if (vx[j]) lx[j] -= d;
            for (int j = 1; j <= n; j++)
                if (vy[j]) ly[j] += d;
        }
    }
    int ans = 0;
    for (int i = 1; i < n; i++) {
        printf("%d ", lx[i]);
        ans += lx[i];
    }
    printf("%d
", lx[n]);
    ans += lx[n];
    for (int i = 1; i < n; i++) {
        printf("%d ", ly[i]);
        ans += ly[i];
    }
    printf("%d
", ly[n]);
    ans += ly[n];
    printf("%d
", ans);
}
int main() {
    while (~scanf("%d", &n)) {
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++) scanf("%d", &s[i][j]);
        KM();
    }
    return 0;
}

以上是关于UVA 11383 Golden Tiger Claw 题解的主要内容,如果未能解决你的问题,请参考以下文章

UVA 11383 Golden Tiger Claw 题解

UVA11383 Golden Tiger Claw——二分图(KM算法)

UVA11383 Golden Tiger Claw——二分图(KM算法)

UVA11383 Golden Tiger Claw

UVA11383 Golden Tiger Claw

Golden Tiger Claw (KM算法)