KM algorithm study notes:

KM algorithm is used to solve the bipartite graph maximum weight matching problem, the problem should be solved by the cost flow.

Recently encountered a problem with the KM algorithm to Inequality, although after conversion can still use cost flow to do, learning to feel the top mark quite useless.

Learning from:

https://blog.csdn.net/c20180630/article/details/71080521

https://www.cnblogs.com/huyufeifei/p/10350763.html


Suppose we solve the biggest problem right exact match, and then discuss how to do after the non-exact match.

Set \ (A [i] [j] \) is the i-th point to the left of the j-th point on the right side of the largest weight, that is, if no -inf.

A start point to the left, is defined scaling \ (HL [X] \) , the initial value of \ (X \) maximum weight value of the edge, to the right of the dot, but also the definition of scaling \ (hr [y ] \) , the initial value is zero.

Define the current is equal to the sub-graph: reserved only \ (hl [x] + hr [y] = a [x] [y] \) side.

Essentially similar algorithms and Hungary algorithm, it is required to find a matching point for each point.

Therefore, the process is as follows:
enumerate each point x of the left half, to try to find a match x is equal to the current submap using the Hungarian algorithm.

If not, find a minimum weight D, the point has been traversed to the left hl- = D, the point has been traversed to the right of hr- = D, can be found in the left point and more certain than the 1 (on the right because x no matching point), so the total weight - = D, to achieve a minimum expansion.

This weight value D is not legitimate those sides of the smallest \ (HL [X] HR + [Y] -a [X] [Y] \) .

Direct write to the complexity of the card will be \ (O (the n-^ 4) \) .

http://uoj.ac/problem/80 this problem and could not pass.

Code(DFS):

#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
#define ff(i, x, y) for(int i = x, _b = y; i <  _b; i ++)
#define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
using namespace std;

const int N = 405;

int nl, nr, m, x, y, z;
int a[N][N];

const int inf = 1e9;

int hl[N], hr[N], vl[N], vr[N], chox[N], choy[N];
int mi;

int find(int x) {
    vl[x] = 1;
    fo(y, 1, nr) {
        if(vr[y]) continue;
        int t = hl[x] + hr[y] - a[x][y];
        if(!t) {
            vr[y] = 1;
            if(!choy[y] || find(choy[y])) {
                chox[x] = y; choy[y] = x;
                return 1;
            }
        } else mi = min(mi, t);
    }
    return 0;
}

int main() {
    scanf("%d %d %d", &nl, &nr, &m);
    fo(i, 1, m) {
        scanf("%d %d %d", &x, &y, &z);
        a[x][y] += z;
    }
    fo(i, 1, nl) fo(j, 1, nr) hl[i] = max(hl[i], a[i][j]);
    int Nr = nr; nr = max(nr, nl);
    fo(i, 1, nl) {
        while(1) {
            memset(vl, 0, sizeof vl);
            memset(vr, 0, sizeof vr);
            mi = inf;
            if(find(i)) break;
            fo(j, 1, nl) if(vl[j]) hl[j] -= mi;
            fo(j, 1, nr) if(vr[j]) hr[j] += mi;
        }
    }
    ll ans = 0;
    fo(i, 1, nl) ans += hl[i];
    fo(i ,1, nr) ans += hr[i];
    pp("%lld\n", ans);
    fo(i, 1, nl) pp("%d ", a[i][chox[i]] ? chox[i] : 0);
}

Then there is a BFS found on the Internet written, I understand for a long time, though not essentially different.

Code(BFS):

#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
#define ff(i, x, y) for(int i = x, _b = y; i <  _b; i ++)
#define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
using namespace std;

const int N = 405;

int nl, nr, m, x, y, z;
int a[N][N];

const int inf = 1e9;

int hl[N], hr[N], vl[N], vr[N], chox[N], choy[N], sla[N], pre[N];
int mi;

void bfs(int x) {
    memset(sla, 127, sizeof sla);
    memset(pre, 0, sizeof pre);
    memset(vl, 0, sizeof vl);
    memset(vr, 0, sizeof vr);
    int u = 0, nu;
    choy[u] = x;
    do {
        x = choy[u];
        ll D = 1e9;
        vr[u] = 1;
        fo(y, 1, nr) if(!vr[y]) {
            ll t = hl[x] + hr[y] - a[x][y];
            if(t < sla[y]) {
                sla[y] = t;
                pre[y] = u;
            }
            if(sla[y] < D) {
                D = sla[y], nu = y;
            }
        }
        hl[choy[0]] -= D; hr[0] += D;
        fo(i, 1, nr) {
            if(vr[i]) {
                hl[choy[i]] -= D, hr[i] += D;
            } else sla[i] -= D;
        }
        u = nu;
    } while(choy[u]);
    for(; u; u = pre[u])
        choy[u] = choy[pre[u]];
}

int main() {
    scanf("%d %d %d", &nl, &nr, &m);
    fo(i, 1, m) {
        scanf("%d %d %d", &x, &y, &z);
        a[x][y] += z;
    }
    fo(i, 1, nl) fo(j, 1, nr) hl[i] = max(hl[i], a[i][j]);
    nr = max(nr, nl);
    fo(i, 1, nl) bfs(i);
    ll ans = 0;
    fo(i, 1, nl) ans += hl[i];
    fo(i, 1, nr) ans += hr[i];
    fo(i, 1, nr) chox[choy[i]] = i;
    pp("%lld\n", ans);
    fo(i, 1, nl) pp("%d ", a[i][chox[i]] ? chox[i] : 0);
}

Question 1:

Not match exactly how to do?

method:

\ (a [x] [y ] \) if there is no edge, the \ (A [X] [Y] = 0 \) , and if left points more than the right point, the right to make some of the null point, so that when a and it does not match the time point of the edge points, corresponding to not selected.

Question 2:
bfs wording can only exist side adjacency matrix, is between the two sides must have two points, or UOJ sample questions that will hang.

This is because of the special nature of the wording bfs, the reader can understand the secret of their own (bfs out of order is not necessarily the optimal augmenting paths).

Question 3:

Speaking at the beginning of Inequality, the following questions:

https://ac.nowcoder.com/acm/contest/4010/I

\(x[i]+y[j]>=a[i][j]>=0\)

Seeking \ (\ sum x + \ sum y \) minimum.

Done directly KM, the last remaining top mark is the answer, is the greatest right to the top mark and match, so you can stream direct costs.

I submit:

https://ac.nowcoder.com/acm/contest/view-submission?submissionId=42982840

Guess you like

Origin www.cnblogs.com/coldchair/p/12309736.html