码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 2255 奔小康发大财

时间:2015-11-22 21:55:25      阅读:143      评论:0      收藏:0      [点我收藏+]

标签:

传送门

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\n", 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);

失灵。

 

HDU 2255 奔小康发大财

标签:

原文地址:http://www.cnblogs.com/Patt/p/4986792.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!