njupt-1134-Christmas

Christmas

时间限制(普通/Java) :  2000 MS/ 6000 MS          运行内存限制 : 65536 KByte
总提交 : 33            测试通过 : 11 

比赛描述

     Christmas day is coming . There will be a ball in Christmas Eve . N men and N women will take part in the ball . One man and one woman form a pair . As we know , if there is a great difference in age or in height , the pair will be very disappointed . Now we define the disappointment between one man and one woman as :

     Where Hi is the height of person i and AGEi is the age of that person . Your task is to find a plan to form N pairs , with the max disappointment value minimized .



输入

Input may contain several test data sets.
For each data set , the first line contains an integer N ( 0 < N <= 500 ) ;
The first line is followed by 2N lines . The first N lines describe N men , and the last N lines describe N women . Each line contains two integers , the height and the age of a person . 
You can assume that the height of one person is between 100cm and 200cm and the age between 10 and 60 . 
Input is ended by N = 0 , which should not be processed.

输出

For each data set , print the answer in a single line.

样例输入

2
141 27
134 10
169 34
178 18
0

样例输出

1801

题目来源

NUPT ACM

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std ;
 
const int Max = 99999999 ;
 
int K,N,M ;             //二分图中x和y中点的数目
int H[505],A[505] , Hw[505],Aw[505] ;
bool visit[505] ;        //记录y中节点是否使用
int result[505] ;      //记录当前与y节点相连的x的节点
int map[505][505] ;    //记录连接x和y的边
int low , high ,mid , way ;
 
bool hungary(int u)                                        //匈牙利算法
{
    for (int v = 0; v < M; v ++)
    {
        if (!visit[v] && map[u][v] <= mid)           //map[u][v] <= mid,这句是二分的关键,在普通的二分图匹配map[i][j] = 0/1
        {
            visit[v] = true;
 
            if (result[v]  == -1 || hungary(result[v]))
            {
                result[v] = u;
 
                return true;
            }
        }
    }
    
    return false;
}
 
int match()
{
    int ret;
 
    memset(result, -1, sizeof(result));
 
    ret = 0;
 
    for (int u = 0; u < N; u ++)
    {
        memset(visit, false, sizeof(visit));
 
        if (hungary(u))
        {
            ret ++;
        }
    }
 
    return ret;
}
 
int main()
{
    while(scanf("%d",&K),K!=0)
    {
        memset(map,0,sizeof(map)) ;
        N = K  ;
        for(int i = 0 ;  i < N ;i ++)
        {
            scanf("%d %d",&H[i],&A[i]) ;
        }
 
        M = K ;
        for(int j = 0 ; j < M ; j ++)
        {
           scanf("%d %d",&Hw[j],&Aw[j]) ;
        }
 
        for(int i = 0 ; i < N ; i ++)
        {
            for(int j = 0 ; j < M ; j ++)
            {
                map[i][j] = (H[i]-Hw[j])*(H[i]-Hw[j])+(A[i]-Aw[j])*(A[i]-Aw[j]) ;
            }
        }
 
        low =  Max ;
        high = - Max ;
        for(int i = 0 ; i < N ; i ++)	   //求出最大和最小的map[][];
        {
            for(int j = 0 ; j < M ; j ++)
            {
                low = min(low,map[i][j]) ;
                high = max(high,map[i][j]) ;
            }
        }
        while(low < high)                //二分过程
        {
            mid = (low + high ) / 2 ;
            way = match() ;
            if(way >= M)
            {
                high = mid ;
            }
            else 
            {
                low = mid + 1 ;
            }
        }
        printf("%d\n",low) ;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值