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

题目链接:http://acm.acmcoder.com/showproblem.php?pid=2255

题意:中文

//KM算法模板题,用来测试一下模板

代码:

#include <stdio.h>
#include <ctime>
#include <math.h>
#include <limits.h>
#include <complex>
#include <string>
#include <functional>
#include <iterator>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <list>
#include <bitset>
#include <sstream>
#include <iomanip>
#include <fstream>
#include <iostream>
#include <ctime>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <time.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>

using namespace std;

const int N = 310;
const int INF = 0x3f3f3f3f;

int nx, ny;

int g[N][N];
int linker[N], lx[N], ly[N];
int slack[N];
bool visx[N], visy[N];

bool dfs(int x)
{
    visx[x] = true;
    for (int y = 0; y < ny; y++)
    {
        if (visy[y]) continue;
        int tmp = lx[x] + ly[y] - g[x][y];
        if (tmp == 0)
        {
            visy[y] = true;
            if (linker[y] == -1 || dfs(linker[y]))
            {
                linker[y] = x;
                return true;
            }
        }
        else if (slack[y] > tmp)
            slack[y] = tmp;
    }
    return false;
}

int KM()
{
    memset(linker,-1,sizeof(linker));
    memset(ly,0,sizeof(ly));
    for (int i = 0; i < nx; i++)
    {
        lx[i] = -INF;
        for (int j = 0; j < ny; j++)
        {
            if (g[i][j] > lx[i])
                lx[i] = g[i][j];
        }
    }
    for (int x = 0; x < nx; x++)
    {
        for (int i = 0; i < ny; i++)
            slack[i] = INF;
        while (true)
        {
            memset(visx, false, sizeof(visx));
            memset(visy, false, sizeof(visy));
            if (dfs(x)) break;
            int d = INF;
            for (int i = 0; i < ny; i++)
                if (!visy[i] && d > slack[i])
                    d = slack[i];
            for (int i = 0; i < nx; i++)
                if (visx[i])
                    lx[i] -= d;
            for (int i = 0; i < ny; i++)
            {
                if (visy[i]) ly[i] += d;
                else slack[i] -= d;
            }
        }
    }
    int res = 0;
    for (int i = 0; i < ny; i++)
    {
        if (linker[i] != -1)
            res += g[linker[i]][i];
    }
    return res;
}

int main()
{
    int n;
    while (scanf("%d", &n) != EOF)
    {
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
                scanf("%d",&g[i][j]);
        nx = ny = n;
        printf("%d\n",KM());
    }
    return 0;
}
时间: 2024-12-29 07:14:32

hdu 2255 奔小康赚大钱【最大权匹配】的相关文章

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

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家老百姓,考

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

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

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

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

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 解题思路: 了解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 奔小康赚大钱 KM算法题解

KM算法求的是完备匹配下的最大权匹配,是Hungary算法的进一步,由于Hungary算法是最大匹配的算法,不带权. 经典算法,想不出来的了,要參考别人的.然后消化吸收吧. 由于真的非常复杂的算法. 我理解算法匹配思想: 1 開始的时候,全部边都记录自己的最优匹配,无论有没有冲突 2 递归循环的时候.假设找不到自己的最优匹配,那么就找次要匹配 3 次要匹配不行,继续找下一个次优匹配,全部点都一定要找到解 难点: 怎样记录这些信息,以便循环处理全部点. 牵涉到非常多什么增广路,交错树之类的,名词,

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)边