• hdu2255 KM模板


    #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
    ", km());
        }
    
    }
  • 相关阅读:
    超详细动画彻底掌握深度优先,广度优先遍历!
    拜托,别再问我什么是 B+ 树了
    高性能短链设计
    Gradle build 太慢,可能是你使用的姿势不对
    看完这些,你也能成技术专家
    x58平台 服务器电源配置 tdp
    系统掉盘,机械硬盘掉盘,固态掉盘
    centos7 修改ip和dns
    centos 修改hostname
    TCP三次握手和四次挥手过程
  • 原文地址:https://www.cnblogs.com/takeoffyoung/p/4864833.html
Copyright © 2020-2023  润新知