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

P - 奔小康赚大钱HDU 2255

时间:2015-08-08 21:11:08      阅读:97      评论:0      收藏:0      [点我收藏+]

标签:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 310;
const int INF = 0x3f3f3f3f;
int maps[maxn][maxn], lx[maxn], ly[maxn];
int visx[maxn], visy[maxn], s[maxn], used[maxn], n;
bool Find(int u)
{
    visx[u] = 1;
    for (int i=1; i<=n; i++)
    {
        if (!visy[i] && lx[u]+ly[i] == maps[u][i])
        {
            visy[i] = 1;
            if (!used[i] || Find(used[i]))
            {
                used[i] = u;
                return true;
            }
        }
        else
            s[i] = min (s[i], lx[u]+ly[i]-maps[u][i]);
    }
    return false;
}
int KM ()
{
    memset (used, 0, sizeof(used));
    memset (lx, 0, sizeof(lx));
    memset (ly, 0, sizeof(ly));
    for (int i=1; i<=n; i++)
        for (int j=1; j<=n; j++)
        lx[i] = max (lx[i], maps[i][j]);
    for (int i=1; i<=n; i++)
    {
        for (int j=1; j<=n; j++)
            s[j] = INF;
        while (1)
        {
            memset (visx, 0, sizeof(visx));
            memset (visy, 0, sizeof(visy));
            if (Find(i))
                break;
            int d = INF;
            for (int j=1; j<=n; j++)
                if (!visy[j])
                    d = min (d, s[j]);
            for (int j=1; j<=n; j++)
            {
                if (visx[j])
                    lx[j] -= d;
                if (visy[j])
                    ly[j] += d;
            }
        }
    }
    int res = 0;
    for (int i=1; i<=n; i++)
        res += maps[used[i]][i];
    return res;
}
int main ()
{
    while (scanf("%d", &n) != EOF)
    {
        for (int i=1; i<=n; i++)
            for (int j=1; j<=n; j++)
            scanf("%d", &maps[i][j]);
        printf("%d\n", KM());
    }
    return 0;
}

P - 奔小康赚大钱HDU 2255

标签:

原文地址:http://www.cnblogs.com/mengzhong/p/4713775.html

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