码迷,mamicode.com
首页 > 编程语言 > 详细

uva 11383 Golden Tiger Claw (KM算法)

时间:2015-08-18 22:56:01      阅读:253      评论:0      收藏:0      [点我收藏+]

标签:

uva 11383 Golden Tiger Claw

题目大意:给定一个N×N的矩阵,每个格子里都有一个正整数w(i,j)。你的任务是给每行确定一个整数row(i), 每列也确定一个整数col(i),使得对于格子(i,j)w(i,j)<=row(i)+col(j)。所有row(i)col(j)的总和最小。

解题思路:KM算法。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
using namespace std;

const int N = 5000;
const int INF = 0x3f3f3f3f;
typedef long long ll;
int n;
int W[N][N];
int Lx[N], Ly[N];
int left[N];
bool S[N], T[N];

bool match(int i) {
    S[i] = true;
    for (int j = 1; j <= n; j++) {
        if (Lx[i] + Ly[j] == W[i][j] && !T[j]) {
            T[j] = true;
            if (!left[j] || match(left[j])) {
                left[j] = i;
                return true;
            }
        }   
    }
    return false;
}

void update() {
    int a = INF; 
    for (int i = 1; i <= n; i++) {
        if (!S[i]) continue;
        for (int j = 1; j <= n; j++) {
            if (T[j]) continue; 
            a = min(a, Lx[i] + Ly[j] - W[i][j]);
        }
    }
    for (int i = 1; i <= n; i++) {
        if (S[i]) Lx[i] -= a;
        if (T[i]) Ly[i] += a;
    }
}

void KM() {
    //初始时为了使Lx[i]+Ly[j]>=W[i, j]恒成立,令Lx[i]为所有与顶点Xi关联的边的最大权,Ly[j]=0
    for (int i = 1; i <= n; i++) {
        left[i] = Lx[i] = Ly[i] = 0;    
        for (int j = 1; j <= n; j++) {
            Lx[i] = max(Lx[i], W[i][j]);    
        }
    }
    for (int i = 1; i <= n; i++) {
        while (1) {
            for (int j = 1; j <= n; j++) S[j] = T[j] = 0;
            if (match(i)) break;
            else update();
        }   
    }
}

void input() {
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            scanf("%d", &W[i][j]);  
        }   
    }
}

int main() {
    while (scanf("%d", &n) != EOF) {
        input();
        KM();
        int sum = Lx[1];
        printf("%d", Lx[1]);
        for (int i = 2; i <= n; i++) {
            printf(" %d ", Lx[i]);  
            sum += Lx[i];
        }
        puts("");
        printf("%d", Ly[1]);
        sum += Ly[1];
        for (int i = 2; i <= n; i++) {
            printf(" %d", Ly[i]);   
            sum += Ly[i];
        }
        printf("\n%d\n", sum);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不可转载。

uva 11383 Golden Tiger Claw (KM算法)

标签:

原文地址:http://blog.csdn.net/llx523113241/article/details/47760031

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!