/*
km 最小权匹配 左边是树,右边是蚂蚁
*/
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
#define MAXN 105
#define inf 999999999.0
#define eps 1e-5
struct Point
{
double x;
double y;
};
Point tree[MAXN],ant[MAXN];
double w[MAXN][MAXN];
double lx[MAXN],ly[MAXN];//期望
int link[MAXN];//匹配
int visx[MAXN],visy[MAXN];//是否已经匹配
double slack[MAXN];//匹配最小值
int n;
km 最小权匹配 左边是树,右边是蚂蚁
*/
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
#define MAXN 105
#define inf 999999999.0
#define eps 1e-5
struct Point
{
double x;
double y;
};
Point tree[MAXN],ant[MAXN];
double w[MAXN][MAXN];
double lx[MAXN],ly[MAXN];//期望
int link[MAXN];//匹配
int visx[MAXN],visy[MAXN];//是否已经匹配
double slack[MAXN];//匹配最小值
int n;
double dist(Point a,Point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int dfs(int x)
{
visx[x]=1;
for(int y=1;y<=n;y++)
{
if(visy[y]) continue;
//如果y满足匹配的条件
double t=lx[x]+ly[y]-w[x][y];
if(fabs(t)<eps)
{
visy[y]=1;
//如果y没有匹配或者y匹配的那位可以另找其它的y
if(link[y]==-1||dfs(link[y]))
{
link[y]=x;
return 1;
}
}
else if(slack[y]>t)
slack[y]=t;
}
return 0;
}
{
visx[x]=1;
for(int y=1;y<=n;y++)
{
if(visy[y]) continue;
//如果y满足匹配的条件
double t=lx[x]+ly[y]-w[x][y];
if(fabs(t)<eps)
{
visy[y]=1;
//如果y没有匹配或者y匹配的那位可以另找其它的y
if(link[y]==-1||dfs(link[y]))
{
link[y]=x;
return 1;
}
}
else if(slack[y]>t)
slack[y]=t;
}
return 0;
}
void KM()
{
int i,j;
memset(link,-1,sizeof(link));
memset(ly,0,sizeof(ly));
for(i=1;i<=n;i++)
{
lx[i]=-inf;
for(j=1;j<=n;j++)
if(w[i][j]>lx[i])
lx[i]=w[i][j];
}
for(int x=1;x<=n;x++)
{
for(i=1;i<=n;i++)
slack[i]=inf;
while(1)
{
memset(visx,0,sizeof(visx));
memset(visy,0,sizeof(visy));
{
int i,j;
memset(link,-1,sizeof(link));
memset(ly,0,sizeof(ly));
for(i=1;i<=n;i++)
{
lx[i]=-inf;
for(j=1;j<=n;j++)
if(w[i][j]>lx[i])
lx[i]=w[i][j];
}
for(int x=1;x<=n;x++)
{
for(i=1;i<=n;i++)
slack[i]=inf;
while(1)
{
memset(visx,0,sizeof(visx));
memset(visy,0,sizeof(visy));
//如果匹配成功,退出
if(dfs(x)) break;
if(dfs(x)) break;
//找到没有匹配过的最小的匹配值
double d=inf;
for(i=1;i<=n;i++)
if(!visy[i]&&d>slack[i])
d=slack[i];
double d=inf;
for(i=1;i<=n;i++)
if(!visy[i]&&d>slack[i])
d=slack[i];
//这一轮参与的x的期望值减去d
for(i=1;i<=n;i++)
if(visx[i])
lx[i]-=d;
for(i=1;i<=n;i++)
if(visx[i])
lx[i]-=d;
//这一轮参与的y的期望值增加d
for(i=1;i<=n;i++)
if(visy[i])
ly[i]+=d;
else
slack[i]-=d;
for(i=1;i<=n;i++)
if(visy[i])
ly[i]+=d;
else
slack[i]-=d;
}
}
}
}
}
int main()
{
int i,j;
cin>>n;
for(i=1;i<=n;i++)
cin>>ant[i].x>>ant[i].y;
for(i=1;i<=n;i++)
cin>>tree[i].x>>tree[i].y;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
w[i][j]=-dist(tree[i],ant[j]);
KM();
for(i=1;i<=n;i++)
cout<<link[i]<<endl;
}
{
int i,j;
cin>>n;
for(i=1;i<=n;i++)
cin>>ant[i].x>>ant[i].y;
for(i=1;i<=n;i++)
cin>>tree[i].x>>tree[i].y;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
w[i][j]=-dist(tree[i],ant[j]);
KM();
for(i=1;i<=n;i++)
cout<<link[i]<<endl;
}