• codevs 1028 花店橱窗布置 KM算法


    题目链接

    n个花, m个花瓶, 每个花放到一个花瓶里会产生一个值w[i][j], 一个花只能放到一个花瓶里, 一个花瓶只能放一个花, 求产生的最大值。

    带权二分图模板。

    #include <iostream>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <map>
    #include <set>
    #include <string>
    #include <queue>
    #include <stack>
    #include <bitset>
    using namespace std;
    #define pb(x) push_back(x)
    #define ll long long
    #define mk(x, y) make_pair(x, y)
    #define lson l, m, rt<<1
    #define mem(a) memset(a, 0, sizeof(a))
    #define rson m+1, r, rt<<1|1
    #define mem1(a) memset(a, -1, sizeof(a))
    #define mem2(a) memset(a, 0x3f, sizeof(a))
    #define rep(i, n, a) for(int i = a; i<n; i++)
    #define fi first
    #define se second
    typedef pair<int, int> pll;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int mod = 1e9+7;
    const int inf = 1061109567;
    const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
    const int M = 105;
    bool sx[M], sy[M];
    int match[M], w[M][M], n, m, d, lx[M], ly[M];
    void init ()
    {
        memset (w, 0, sizeof(w));
    }
    bool dfs (int u)
    {
        int v; sx[u] = true;
        for (v = 0; v < m; v++)
        {
            if (!sy[v] && lx[u]+ly[v]==w[u][v])
            {
                sy[v] = true;
                if (match[v] == -1 || dfs (match[v]))
                {
                    match[v] = u;
                    return true;
                }
            }
        }
        return false;
    }
    
    int KM ()
    {
        int i, j, k, sum = 0;
        memset (ly, 0, sizeof(ly));
        for (i = 0; i < n; i++)
        {
            lx[i] = -inf;
            for (j = 0; j < m; j++)
                if (lx[i] < w[i][j])
                    lx[i] = w[i][j];
        }
        memset (match, -1, sizeof(match));
        for (i = 0; i < n; i++)
        {
            while (1)
            {
                memset (sx, false, sizeof(sx));
                memset (sy, false, sizeof(sy));
                if (dfs (i))
                    break;
                d = inf;
                for (j = 0; j < n; j++)
                    if (sx[j])
                        for (k = 0; k < m; k++)
                            if (!sy[k])
                                d = min (d, lx[j]+ly[k]-w[j][k]);
                if (d == inf)
                    return -1;
                for (j = 0; j < n; j++)
                    if (sx[j])
                        lx[j] -= d;
                for (j = 0; j < m; j++)
                    if (sy[j])
                        ly[j] += d;
            }
        }
        for (i = 0; i < m; i++)
            if (match[i] > -1)
                sum += w[match[i]][i];
        return sum;
    }
    int main()
    {
        cin>>n>>m;
        for(int i = 0; i<n; i++) {
            for(int j = 0; j<m; j++) {
                scanf("%d", &w[i][j]);
            }
        }
        int ans = KM();
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    第八章 采样
    第七章 优化算法
    第六章 概率图模型
    第五章 非监督学习
    第四章 降维
    第三章 经典算法
    第二章 模型评估
    第一章 特征工程-------------《百面机器学习》
    中等-102,107-二叉树的层序遍历
    字符串单模式匹配 暴力+哈希
  • 原文地址:https://www.cnblogs.com/yohaha/p/5243098.html
Copyright © 2020-2023  润新知