(二分匹配“匈牙利算法”)无题II --HDU --2236

链接:

http://acm.hdu.edu.cn/showproblem.php?pid=2236

代码:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 105
#define INF 0xffffff

///匹配
///只需要用二分找一个区间,
///然后不断枚举这个区间是否可以达到最大匹配,
///一直二分到答案为止。


int G[N][N], ly[N];
int Max, Min, n;
bool used[N];

bool Find(int i)
{
    for(int j=1; j<=n; j++)
    {
        if(!used[j] && G[i][j]>=Min && G[i][j]<=Max)
        {
            used[j] = true;
            if(!ly[j] || Find(ly[j]))
            {
                ly[j] = i;
                return true;
            }
        }
    }
    return false;
}

int XYL()
{
    memset(ly, 0, sizeof(ly));
    int ans = 0;

    for(int i=1; i<=n; i++)
    {
        memset(used, false, sizeof(used));
        if(Find(i))
            ans ++ ;
    }
    return ans;
}

int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        int i, j, MinL=INF, MaxR=-INF;

        scanf("%d", &n);

        for(i=1; i<=n; i++)
        for(j=1; j<=n; j++)
        {
            scanf("%d", &G[i][j]);
            if(MinL > G[i][j]) MinL = G[i][j];
            if(MaxR < G[i][j]) MaxR = G[i][j];
        }

        int L=0, R=MaxR-MinL, ans=0;

        while(L <= R)
        {
            int Mid = (R+L)>>1;

            for(i=0; i<=MaxR-Mid; i++)
            {
                Min = i, Max = i+Mid;
                if(XYL()==n) break;
            }

            if(i<=MaxR-Mid)
            {
                ans = Mid;
                R = Mid - 1;
            }
            else L = Mid + 1;
        }

        printf("%d
", ans);
    }
    return 0;
}
勿忘初心
原文地址:https://www.cnblogs.com/YY56/p/4732664.html