二分图最佳完美匹配——Kuhn-Munkres算法 (最大权匹配)

二分图最大权匹配的代码:

#include 
#include 
#include 
#include 

using namespace std;

#define N 100

class Solution {
public:
    int S[N];
    int left[N]; // the id in left that matches an id in the right column
    int T[N];
    int lx[N];
    int ly[N];
    int matrix[N][N];
    int n;
    bool dfs(int u) {
        S[u] = 1;
        for (int i = 1; i <= n; i++) {
            if (!T[i] && lx[u]+ly[i]==matrix[u][i]) {
                T[i] = 1;
                if (left[i]==0 || dfs(left[i])) {
                    left[i] = u;
                    return true;
                }
            }
        }
        return false;
    }
    int min(int a, int b) { return a < b ? a : b; }
    void update() {
        int a = (1<<30);
        for (int i = 1; i <= n; i++) {
            if (S[i]==0) continue;
            for (int j = 1; j <= n; j++) {
                if (T[j]==1) continue;
                a = min(a, lx[i]+ly[j]-matrix[i][j]);
            }
        }
        for (int i = 1; i <= n; i++) {
            if (S[i]) lx[i] -= a;
            if (T[i]) ly[i] += a;
        }
    }

    void solve() {
        memset(S, 0, sizeof(S));
        memset(T, 0, sizeof(T));
        memset(left, 0, sizeof(left));
        memset(lx, 0, sizeof(lx));
        memset(ly, 0, sizeof(ly));
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) {
            int _max = 0;
            for (int j = 1; j <= n; j++) { 
                scanf("%d", &matrix[i][j]); 
                if (matrix[i][j] > _max) _max = matrix[i][j]; 
            }
            lx[i] = _max;
        }
        for (int i = 1; i <= n; i++) {
            for (;;) {
                // after each update, clear S and T
                memset(S, 0, sizeof(S));
                memset(T, 0, sizeof(T));
                if (dfs(i)) break; else update();
            }
        }
        for (int i = 1; i <= n; i++) printf("(%d,%d) ", i, left[i]); printf("\n");
        int len = 0;
        for (int i = 1; i <= n; i++) len += matrix[left[i]][i];
        printf("len: %d\n", len);
    }
};

int main() {
    Solution solution;
    solution.solve();
    return 0;
}

输入是:

5 
3 5 5 4 1
2 2 0 2 2
2 4 4 1 0
0 1 1 0 0
1 2 1 3 3

最后计算得到最大权 总长度为14



你可能感兴趣的:(算法,编程语言)