无题II hdu 2236(二分枚举区间)

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

====================================================================================

#include<stdio.h>
#include<string.h>

const int MAXN = 107;
const int oo = 1e9+7;

int G[MAXN][MAXN], Ly[MAXN];
int Max, Min, N;
bool used[MAXN];

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) == true)
            ans++;
    }

    return ans;
}

int main()
{
    int T;

    scanf("%d", &T);

    while(T--)
    {
        int i, j, MinL=oo, MaxR=-oo;

        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/liuxin13/p/4730535.html