TakeoffYoung

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
#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());
    }

}

 

posted on 2015-10-09 19:02  TakeoffYoung  阅读(140)  评论(0编辑  收藏  举报