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\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);

失灵。

时间: 2025-01-06 01:51:58

HDU 2255 奔小康发大财的相关文章

hdu 2255 奔小康赚大钱(KM算法)

奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3248    Accepted Submission(s): 1413 Problem Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊.村里共有n间房间,刚好有n家老百姓,考

HDU 2255 ——奔小康赚大钱——————【KM算法裸题】

奔小康赚大钱 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 2255 Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊.村里共有n间房间,刚好有n家老百姓,考虑到每家都要有房住(如果有老百姓没房子住的话,容易引起不安定因素),每家必须分配到

[ACM] HDU 2255 奔小康赚大钱 (二分图最大权匹配,KM算法)

奔小康赚大钱 Problem Description 传说在遥远的地方有一个很富裕的村落,有一天,村长决定进行制度改革:又一次分配房子. 这但是一件大事,关系到人民的住房问题啊. 村里共同拥有n间房间,刚好有n家老百姓,考虑到每家都要有房住(假设有老百姓没房子住的话.easy引起不安定因素),每家必须分配到一间房子且仅仅能得到一间房子. 还有一方面,村长和另外的村领导希望得到最大的效益,这样村里的机构才会有钱.因为老百姓都比較富裕,他们都能对每一间房子在他们的经济范围内出一定的价格,比方有3间房

HDU 2255 奔小康赚大钱 (KM算法 模板)

A - 奔小康赚大钱 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊.村里共有n间房间,刚好有n家老百姓,考虑到每家都要有房住(如果有老百姓没房子住的话,容易引起不安定因素),每家必须分配到一间房子且只能得到一间房子.

HDU 2255 奔小康赚大钱(二分匹配之KM算法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2255 Problem Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊.村里共有n间房间,刚好有n家老百姓,考虑到每家都要有房住(如果有老百姓没房子住的话,容易引起不安定因素),每家必须分配到一间房子且只能得到一间房子. 另一方面,村长和另外的村领导希望得到最大的效益,这样村里的机构才会有钱.由于老百姓

hdu 2255 奔小康赚大钱 最大权匹配KM

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2255 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子.这可是一件大事,关系到人民的住房问题啊.村里共有n间房间,刚好有n家老百姓,考虑到每家都要有房住(如果有老百姓没房子住的话,容易引起不安定因素),每家必须分配到一间房子且只能得到一间房子.另一方面,村长和另外的村领导希望得到最大的效益,这样村里的机构才会有钱.由于老百姓都比较富裕,他们都能对每一间房子在他们的经济

hdu 2255奔小康赚大钱 KM算法模板

题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=2255 一,KM算法:(借助这个题写一下个人对km的理解与km模板) KM算法主要是用来求解图的最优匹配的. 1.带权二分图:  在二分图中每一条边(x.y)相应一个权值Wi这样的二分图叫带权二分图. 一个匹配的权值就是该匹配中全部边的权值之和. 2,最优匹配: 权值最大的一个完美匹配.叫做最优匹配.       <km算法思想> 对于一个带权全然二分图:G(V.E),对于当中每一条边(x.y)边

hdu 2255 奔小康赚大钱 (km算法模板)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2255 解题思路: 了解km算法以后,就可以直接套用km算法,km算法:完备匹配下的最大权匹配, 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 7 #define maxn 310

HDU 2255 - 奔小康赚大钱

Kuhn - Munkres 算法,第一次拍各种问题,不过还是A掉了.. /* ID:esxgx1 LANG:C++ PROG:hdu2255 */ #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; #define LXN 307 #define RXN 307 int