Untitled II hdu2236

Problem Description

This is a simple game in a matrix of n * n, to find the number n such that n number are required and this difference in the number n of maximum and minimum values ​​in different rows and columns in a minimum .

Input

T T represents an integer input data set.
For each line of the input data a first positive integer n (1 <= n <= 100) represents the size of the matrix.
Then n input lines, each line number n x (0 <= x < = 100).

Output

For each number represents a data output minimum difference.

Sample Input

1
4
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4

Sample Output

3

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#define C(i,x) memset(i,x,sizeof(i))
using namespace std;
template<typename T>void read(T &x)
{
    char ch;
    int f=1;
    x=0;
    for(; ch<'0'||ch>'9'; ch=getchar())
        if(ch=='-')
            f=-1;
    for(; ch>='0'&&ch<='9'; ch=getchar())
        x=(x<<1)+(x<<3)+(ch&15);
    x*=f;
}
template<typename T>void print(T x)
{
    if(x<0)
        x*=-1,putchar('-');
    if(x>=10)
        print(x/10);
    putchar(x%10+'0');
}
const int N=200;
const int INF=0x3f3f3f3f;
int minn=INF;
int p,mid=0;
int nxe[N],used[N],mp[N][N];
int n;
bool Find(int x)
{
    for(int i=0; i<n; i++)
    {
        if(!used[i]&&mp[x][i]>=p&&mp[x][i]<=p+mid)
        {
            used[i]=1;
            if(nxe[i]==-1||Find(nxe[i]))
            {
                nxe[i]=x;
                return true;
            }
        }
    }
    return false;
}
bool match()
{
   C(nxe,-1);
  // memset(nxe,-1,sizeof(nxe));
    for(int i=0; i<n; i++)
    {
        C(used,0);
       // memset(used,0,sizeof(used));
        if(!Find(i))
        {
            return false;    //返回false ,若倒过来返回true 是错误的。
        }
    }
    return true;
}
int main()
{
    ios::sync_with_stdio(false);
    int t;
    read(t);
    while(t--)
    {
        //cin>>n;
        read(n);
        int mx=-INF,mi=INF;
        for(int i=0; i<n; i++)
            for(int j=0; j<n; j++)
            {
                read(mp[i][j]);
                mx=max(mx,mp[i][j]);
                mi=min(mi,mp[i][j]);
            }
        int l=0,r=mx-mi;
        int f=0;
        int res;
        while(l<=r)
        {
            mid=(l+r)>>1;
            f=0;
            for(p=mi; p+mid<=mx; p++)
            {
                if(match())
                {
                    f=1;
                    break;
                }
            }
            if(f)
                res=mid,r=mid-1;
            else
                l=mid+1;
        }
        print(res);
        puts("");
    }
    return 0;
}

Thinking

Perfect match bipartite graph. (Ranks into two sets, each vertex must be matched to, or less than n-match)

Binary Search the difference; gradually narrow the difference.

ps

Nxe initialized to be noted that the array 1; the case because the point has a value of 0, it is judged not to match represented by -1.

Guess you like

Origin www.cnblogs.com/xxffxx/p/11978519.html