SGU252 Railway Communication (maximum weight matching of bipartite graph)

Topic link

title meaning:
        a country n towns, m one-way railway. Each railway connects two different towns, and there are no rings in the railway system. Now it is necessary to identify some train running lines that satisfy:
        1     Each railway belongs to at most one train line;
        2     Each town is traversed by at most one train line (by including as a start or end point);
        3     Each town is crossed by at least one train line;
        4     The number of train lines should be as small as possible.
        5     Under the conditions above, the sum of the length of the train running line should be as small as possible.


Ideas:
        05 Years of dissertation topics, place each point u split into points u and out point u ,for ( u , v ) This directed edge, u arrive v Connect a directed edge, the weight is the negative value of the length of the path, and then the maximum weight matching of a bipartite graph is obtained, and the negative value of the obtained maximum value is the minimum value of the original path length. Then find the solved path. If a path is the starting point, then it has only the out point, that is to say u If it is the starting point, only u with matching edges u no matching edges, same u If it is the end, only u with matching edges u No, just look for it. Note that there may be only one point.

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
#include<iostream>
typedef long long ll;
const int maxn = 1e2 + 10;
const int INF = 1e9;
using namespace std;

typedef pair<int, int> pa;
vector<pa> G[maxn];

int w[maxn][maxn], n;
int lx[maxn], ly[maxn];
int from[maxn], m;
bool S[maxn], T[maxn];

bool match(int i) {
    S[i] = true;
    for(int j = 1; j <= n; j++) {
        if(lx[i] + ly[j] != w[i][j] || T[j]) continue;
        T[j] = true;
        if(!from[j] || match(from[j])) {
            from[j] = i;
            return true;
        }
    }
    return false;
}

void update() {
    int a = 1 << 30;
    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() {
    for(int i = 1; i <= n; i++) {
        from[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();
        }
    }
}

int vis[maxn], to[maxn];
vector<int> vec[maxn];

int main() {
    while(scanf("%d %d", &n, &m) != EOF) {
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++) w[i][j] = -INF;
        for(int i = 1; i <= m; i++) {
            int u, v, c;
            scanf("%d %d %d", &u, &v, &c);
            w[u][v] = -c;
        }
        KM();
        int ans = 0, num = 0;
        for(int i = 1; i <= n; i++) if(w[from[i]][i] != -INF) ans += w[from[i]][i];
        memset(vis, 0, sizeof vis);
        memset(to, -1, sizeof to);
        for(int i = 0; i < maxn; i++) vec[i].clear();
        for(int i = 1; i <= n; i++) {
            if(w[from[i]][i] != -INF) {
                to[from[i]] = i;
                vis[i] = 1;
            }
        }
        for(int i = 1; i <= n; i++) {
            if(to[i] == -1 && !vis[i]) { vec[num].push_back(i); num++; continue; }
            if(~to[i] && !vis[i]) { ///起始点
                int x = i;
                while(~x) {
                    vec[num].push_back(x);
                    x = to[x];
                }
                num++;
            }
        }
        printf("%d %d\n", num, -ans);
        for(int i = 0; i < num; i++) {
            printf("%d", vec[i].size());
            for(int j = 0; j < vec[i].size(); j++) printf(" %d", vec[i][j]);
            printf("\n");
        }
    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324840490&siteId=291194637