Christmas
总提交 : 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) ;
}
}