zoukankan      html  css  js  c++  java
  • HDU 2255 奔小康发大财

    传送门

    Solution:

    KM算法

    关于KM算法有一篇极好的文档http://www.cse.ust.hk/~golin/COMP572/Notes/Matching.pdf

    Implementation:

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <climits>
    using namespace std;
    const int N(305);
    
    int w[N][N];
    int Lx[N], Ly[N], slack[N];
    bool S[N], T[N];
    int match[N];
    int n;
    
    bool dfs(int u)
    {
        S[u]=true;
        for(int v=1; v<=n; v++)
        {
            if(T[v])
            {
                continue;    
            } 
            int tmp=Lx[u]+Ly[v]-w[u][v];
            if(tmp==0)
            {
                T[v]=true;
                if(!match[v] || dfs(match[v]))
                {
                    match[v]=u;
                    return true;
                }
            }
            else
            {
                slack[v]=min(slack[v], tmp);
            }
        }
        return false;
    }
    
    void KM()
    {
        memset(match, 0, sizeof(match));
        memset(Lx, 0x3f, sizeof(Lx));
        memset(Ly, 0x3f, sizeof(Ly));
    
        for(int i=1; i<=n; i++)    //phase
        {
    
            for(int i=1; i<=n; i++)
            {
                slack[i]=INT_MAX;    //error-prone
            }    
            for(int a; ;)
            {
                memset(S, 0, sizeof(S));
                memset(T, 0, sizeof(T));
                if(dfs(i)) break;
                a=INT_MAX;
                for(int j=1; j<=n; j++)
                {
                    if(!T[j])
                    {
                        a=min(a, slack[j]);
                    }
                }
                for(int j=1; j<=n; j++)
                {
                    if(S[j]) 
                    {
                        Lx[j]-=a;
                    }
                    if(T[j])
                    {
                        Ly[j]+=a;
                    }
                    else
                    {
                        slack[j]-=a;
                    }
                }
            }
        }
        int res=0;
        for(int i=1; i<=n; i++)
        {
            res+=w[match[i]][i];
        }
        printf("%d
    ", res);
    }
    
    int main()
    {
        for(; ~scanf("%d", &n); )
        {
            for(int i=1; i<=n; i++)
            {
                for(int j=1; j<=n; j++)
                {
                    scanf("%d", w[i]+j);
                }
            }
            KM();
        }
    }

    Error-prone:

    我把Lx, Ly, slack都初始化成0x3f3f3f3f,导致dfs中

    slack[v]=min(slack[v], tmp);

    失灵。

  • 相关阅读:
    第七讲 宋词:婉约之曲与豪放之声
    P2024 食物链
    可以吹一年的事
    信息传递
    11.11模拟赛总结(又名斗地主战记)
    11.9模拟赛总结
    扩展欧几里得(exgcd模板)
    发糖果(拓扑排序模板)
    高斯消元
    关于我
  • 原文地址:https://www.cnblogs.com/Patt/p/4986792.html
Copyright © 2011-2022 走看看