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

    /*  gyt
           Live up to every day            */
    #include<cstdio>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<stack>
    #include<cstring>
    #include<queue>
    #include<set>
    #include<string>
    #include<map>
    #include <time.h>
    #define PI acos(-1)
    using namespace std;
    typedef long long ll;
    typedef double db;
    const int maxn = 400;
    const ll maxm = 1e7;
    const int mod = 1e9+7;
    const int INF = 0x3f3f3f;
    const ll inf = 1e14 + 5;
    const db eps = 1e-9;
    const ll Max=1e19;
    int mapp[maxn][maxn], visx[maxn], visy[maxn];
    int lx[maxn], ly[maxn];
    int match[maxn];
    int n;
    
    int hungry(int u) {
        visx[u] = true;
        for(int i = 0; i < n; ++i)
        {
            if(!visy[i] && lx[u] + ly[i] == mapp[u][i])
            {
                visy[i] = true;
                if(match[i] == -1 || hungry(match[i]))
                {
                    match[i] = u;
                    return true;
                }
            }
        }
        return false;
    }
    void KM() {
        int temp;
        memset(lx, 0, sizeof(lx)); //初始化顶标
        memset(ly, 0, sizeof(ly)); //ly[i]为0
        for(int i = 0; i < n; ++i) //lx[i]为权值最大的边
            for(int j = 0; j < n; ++j)
                lx[i] = max(lx[i], mapp[i][j]);
        for(int i = 0; i < n; ++i) //对n个点匹配
        {
            while(1)
            {
                memset(visx, false, sizeof(visx));
                memset(visy, false, sizeof(visy));
                if(hungry(i)) //匹配成功
                    break;
                else //匹配失败,找最小值
                {
                    temp = INF;
                    for(int j = 0; j < n; ++j) //x在交错树中
                        if(visx[j])
                            for(int k = 0; k < n; ++k) //y在交错树外
                                if(!visy[k] && temp > lx[j] + ly[k] - mapp[j][k])
                                    temp = lx[j] + ly[k] - mapp[j][k];
                    for(int j = 0; j < n; ++j) //更新顶标
                    {
                        if(visx[j])
                            lx[j] -= temp;
                        if(visy[j])
                            ly[j] += temp;
                    }
                }
            }
        }
    }
    void solve() {
         int ans;
        while(scanf("%d", &n) != EOF)
        {
            ans = 0;
            memset(match, -1, sizeof(match));
            for(int i = 0; i < n; i++)
                for(int j = 0; j < n; j++)
                    scanf("%d", &mapp[i][j]);
            KM();
            for(int i = 0; i < n; i++) //权值相加
                ans += mapp[match[i]][i];
            printf("%d
    ", ans);
        }
    }
    int main() {
        int t=1;
        //freopen("in.txt", "r", stdin);
        //scanf("%d", &t);
    
        while(t--)
            solve();
    }
  • 相关阅读:
    事后诸葛亮
    团队作业6--展示博客(Alpha版本)
    团队作业5——测试与发布(Alpha版本)
    团队作业2:需求分析&原型设计
    团队编程作业1-团队展示与选题
    结对编程1
    TeamViewer app案例分析
    第一次作业--四则运算
    【Alpha】Daily Scrum Meeting 集合贴
    【Alpha】Daily Scrum Meeting——Day3
  • 原文地址:https://www.cnblogs.com/gggyt/p/7263775.html
Copyright © 2011-2022 走看看