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

来源:互联网 发布:excel如何保护数据 编辑:程序博客网 时间:2024/06/05 05:31

题目链接: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;}
0 0
原创粉丝点击