zoukankan      html  css  js  c++  java
  • 图匹配板子

    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;
    }
    
  • 相关阅读:
    【leetcode】1215.Stepping Numbers
    【leetcode】1214.Two Sum BSTs
    【leetcode】1213.Intersection of Three Sorted Arrays
    【leetcode】1210. Minimum Moves to Reach Target with Rotations
    【leetcode】1209. Remove All Adjacent Duplicates in String II
    【leetcode】1208. Get Equal Substrings Within Budget
    【leetcode】1207. Unique Number of Occurrences
    【leetcode】689. Maximum Sum of 3 Non-Overlapping Subarrays
    【leetcode】LCP 3. Programmable Robot
    【leetcode】LCP 1. Guess Numbers
  • 原文地址:https://www.cnblogs.com/tkandi/p/10815454.html
Copyright © 2011-2022 走看看