• 图匹配板子


    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
    ", 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
    ", 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
    ", ret);
        for (int i = 1; i <= n; ++i)
            printf("%d ", linkx[i]);
        puts("");
        return 0;
    }
    
  • 相关阅读:
    【树状数组套权值线段树】bzoj1901 Zju2112 Dynamic Rankings
    【权值线段树】bzoj3224 Tyvj 1728 普通平衡树
    【转载】【树形DP】【数学期望】Codeforces Round #362 (Div. 2) D.Puzzles
    ReStart
    Good-Bye
    【分块打表】bzoj1662 [Usaco2006 Nov]Round Numbers 圆环数
    【分块打表】bzoj1026 [SCOI2009]windy数
    【分块打表】bzoj3798 特殊的质数
    【分块打表】bzoj3758 数数
    【线段树】bzoj3995 [SDOI2015]道路修建
  • 原文地址:https://www.cnblogs.com/tkandi/p/10815454.html
Copyright © 2020-2023  润新知