Sicily 1684. Christmas

1684. Christmas

Constraints

Time Limit: 5 secs, Memory Limit: 32 MB

Description

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:

F(i,j)=(Hi-Hj)^2+(AGEi-AGEj)^2

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

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 is between 10 and 60.

Input is ended by N=0, which should not be processed.

Output

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

Sample Input

2141 27134 10169 34178 180

Sample Output

1801

// Problem#: 1684
// Submission#: 3589186
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <stdio.h>
#include <string.h>

const int MAXN = 1001;

int N;
int disp[MAXN][MAXN];
int heightm[MAXN], heightw[MAXN];
int agem[MAXN], agew[MAXN];
int nx, ny, g[MAXN][MAXN], sy[MAXN], cx[MAXN], cy[MAXN];

int path(int u) {
    for (int v = 1; v <= ny; v++)
        if (g[u][v] && !sy[v]) {
            sy[v] = 1;
            if (!cy[v] || path(cy[v])) {
                cx[u] = v;
                cy[v] = u;
                return 1;
            }
        }
    return 0;
}

int maxmatch() {
    int i, ret = 0;
    memset(cx, 0, sizeof(cx));
    memset(cy, 0, sizeof(cy));
    for (i = 1; i <= nx; i++)
        if (!cx[i]) {
            memset(sy, 0, sizeof(sy));
            ret += path(i);
        }
    return ret;
}

void buildgraph(int x) {
    int i, j;
    nx = ny = N;
    memset(g, 0, sizeof(g));
    for (i = 1; i <= N; i++)
        for (j = 1; j <= N; j++)
            if (disp[i][j] <= x) g[i][j] = 1;
            else g[i][j] = 0;
}

int main() {
    int i, j, p, q, ans, left, right;
    while (scanf("%d", &N) == 1) {
        if (N == 0) break;
        for (i = 1; i <= N; i++) scanf("%d%d", heightm + i, agem + i);
        for (i = 1; i <= N; i++) scanf("%d%d", heightw + i, agew + i);
        left = 1000000000;
        right = 0;
        for (i = 1; i <= N; i++) {
            for (j = 1; j <= N; j++) {
                p = heightm[i] - heightw[j];
                q = agem[i] - agew[j];
                disp[i][j] = p * p + q * q;
                if (disp[i][j] < left) left = disp[i][j];
                if (disp[i][j] > right) right = disp[i][j];
            }
        }
        while (left <= right) {
            int mid = (left + right) / 2;
            buildgraph(mid);
            int ret = maxmatch();
            if (ret == N) {
                ans = mid;
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}                                 


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值