图匹配板子

uoj#78. 二分图最大匹配

#include <bits/stdc++.h>

using namespace std;

const int N = 505;

int n, m, e;
int w[N][N];

int vis[N], linkx[N], linky[N];

bool Find(int x) {
    for (int i = 1; i <= m; ++i)
        if (!vis[i] && w[x][i]) {
            vis[i] = 1;
            if (!linky[i] || Find(linky[i])) {
                linky[i] = x;
                return 1;
            }
        }
    return 0;
}

int main() {
    scanf("%d%d%d", &n, &m, &e);
    for (int i = 1; i <= e; ++i) {
        int u, v;
        scanf("%d%d", &u, &v);
        w[u][v] = 1;
    }
    int ret = 0;
    for (int i = 1; i <= n; ++i) {
        memset(vis, 0, sizeof(vis));
        if (Find(i)) ++ret;
    }
    for (int i = 1; i <= m; ++i)
        if (linky[i]) linkx[linky[i]] = i;
    printf("%d\n", ret);
    for (int i = 1; i <= n; ++i)
        printf("%d ", linkx[i]);
    puts("");
    return 0;
}


uoj#80. 二分图最大权匹配
DFS版(复杂度为\(O(n^4)\) Time Limit Exceeded)

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const int N = 405;
const LL INF = ~0ULL >> 1;

int n, m, e;
int w[N][N];
int vis[N], linkx[N], linky[N];
LL lx[N], ly[N], slack;

bool Find(int x) {
    for (int i = 1; i <= max(n, m); ++i)
        if (!vis[i]) {
            if (lx[x] + ly[i] == w[x][i]) {
                vis[i] = 1;
                if (!linky[i] || Find(linky[i])) {
                    linky[i] = x;
                    return 1;
                }
            } else slack = min(slack, lx[x] + ly[i] - w[x][i]);
        }
    return 0;
}

int main() {
    scanf("%d%d%d", &n, &m, &e);
    for (int i = 1; i <= e; ++i) {
        int u, v;
        scanf("%d%d", &u, &v);
        scanf("%d", &w[u][v]);
        lx[u] = max<LL>(lx[u], w[u][v]);
        ly[v] = max<LL>(ly[v], w[u][v]);
    }
    for (int i = 1; i <= max(n, m); ++i)
        for (; ; ) {
            memset(vis, 0, sizeof(vis));
            slack = INF;
            if (Find(i)) break;
            lx[i] -= slack;
            for (int j = 1; j <= max(n, m); ++j)
                if (vis[j]) {
                    lx[linky[j]] -= slack;
                    ly[j] += slack;
                }
        }
    LL ret = 0;
    for (int i = 1; i <= max(n, m); ++i) {
        ret += lx[i];
        ret += ly[i];
        if (w[linky[i]][i]) linkx[linky[i]] = i;
    }
    printf("%lld\n", ret);
    for (int i = 1; i <= n; ++i)
        printf("%d ", linkx[i]);
    puts("");
    return 0;
}

BFS版(复杂度为\(O(n^3)\)

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

template <class T>
inline bool Cmin(T &a, T b) {
    return (a > b) ? (a = b, 1) : 0;
}

const int N = 405;
const LL INF = ~0ULL >> 1;

int n, m, e;
int w[N][N];
int vis[N], linkx[N], linky[N];
LL lx[N], ly[N], slack[N], slap[N];

void BFS(int x) {
    memset(vis, 0, sizeof(vis));
    fill(slack, slack + max(n, m) + 1, INF);
    memset(slap, 0, sizeof(slap));
    linky[0] = x;
    int y = 0;
    while (linky[y]) {
        int s = 0;
        x = linky[y];
        vis[y] = 1;
        for (int i = 1; i <= max(n, m); ++i)
            if (!vis[i]) {
                if (Cmin(slack[i], lx[x] + ly[i] - w[x][i])) slap[i] = y;
                if (slack[s] > slack[i]) s = i;
            }
        LL t = slack[s];
        for (int i = 0; i <= max(n, m); ++i)
            if (vis[i]) {
                lx[linky[i]] -= t;
                ly[i] += t;
            } else if (slack[i] < INF) slack[i] -= t;
        y = s;
    }
    for (; y; y = slap[y]) linky[y] = linky[slap[y]];
    return;
}

int main() {
    scanf("%d%d%d", &n, &m, &e);
    for (int i = 1; i <= e; ++i) {
        int u, v;
        scanf("%d%d", &u, &v);
        scanf("%d", &w[u][v]);
        lx[u] = max<LL>(lx[u], w[u][v]);
        ly[v] = max<LL>(ly[v], w[u][v]);
    }
    for (int i = 1; i <= max(n, m); ++i) BFS(i);
    LL ret = 0;
    for (int i = 1; i <= max(n, m); ++i) {
        ret += lx[i];
        ret += ly[i];
        if (w[linky[i]][i]) linkx[linky[i]] = i;
    }
    printf("%lld\n", ret);
    for (int i = 1; i <= n; ++i)
        printf("%d ", linkx[i]);
    puts("");
    return 0;
}
posted @ 2019-05-05 18:30  tkandi  阅读(118)  评论(0编辑  收藏  举报