1 /*LA4043 2 1<=n<=100 3 给定两个集合A,B,每个集合的n个元素的坐标,以欧几里得距离为权值。 4 求一个A到B的一一映射,每一对相互连线,使得,没有任何两条线是相交的。 5 6 这道题有个特解:A和B的最佳匹配(使负的权值和最大),因为两条交叉的线,能换成两条不交叉的,从而增大负权值和。 7 */ 8 #include <cmath> 9 #include <algorithm> 10 #include <stdlib.h> 11 #include <iostream> 12 #include <string.h> 13 #include <stdio.h> 14 #include <stack> 15 #include <set> 16 #include <map> 17 #include <vector> 18 #define typed double 19 #define INF 1<<30 20 #define maxn 110 21 #define eps 1e-6 22 using namespace std; 23 int n; 24 typed W[maxn][maxn]; 25 typed Lx[maxn],Ly[maxn]; 26 int lef[maxn]; 27 bool S[maxn],T[maxn]; 28 29 bool match(int i){ 30 S[i]=true; 31 for(int j=1;j<=n;j++) if (fabs(Lx[i]+Ly[j]-W[i][j])<eps && !T[j]){ 32 T[j]=true; 33 if (!lef[j] || match(lef[j])){ 34 lef[j]=i; 35 return true; 36 } 37 } 38 return false; 39 } 40 41 void update(){ 42 typed a=INF; 43 for(int i=1;i<=n;i++) if(S[i]){ 44 for(int j=1;j<=n;j++) if(!T[j]) 45 a=min(a,Lx[i]+Ly[j]-W[i][j]); 46 } 47 for(int i=1;i<=n;i++){ 48 if (S[i]) Lx[i]-=a; 49 if (T[i]) Ly[i]+=a; 50 } 51 } 52 void KM(){ 53 for(int i=1;i<=n;i++){ 54 lef[i]=Lx[i]=Ly[i]=0; 55 for(int j=1;j<=n;j++){ 56 Lx[i]=max(Lx[i],W[i][j]); 57 } 58 } 59 for(int i=1;i<=n;i++){ 60 for(;;){ 61 for(int j=1;j<=n;j++) S[j]=T[j]=false; 62 if (match(i)) break;else update(); 63 } 64 } 65 } 66 typed AX[maxn],AY[maxn]; 67 typed BX[maxn],BY[maxn]; 68 double dis(int u,int v){ 69 double ans=-sqrt((BX[u]-AX[v])*(BX[u]-AX[v])+(BY[u]-AY[v])*(BY[u]-AY[v])); 70 return ans; 71 } 72 void read(){ 73 for(int i=1;i<=n;i++) scanf("%lf%lf",&AX[i],&AY[i]); 74 for(int i=1;i<=n;i++) scanf("%lf%lf",&BX[i],&BY[i]); 75 for(int i=1;i<=n;i++) 76 for(int j=1;j<=n;j++) 77 W[i][j]=dis(i,j); 78 } 79 int t=0; 80 int main(){ 81 while(cin>>n){ 82 t++; 83 read(); 84 KM(); 85 if (t>1) printf(" "); 86 for(int i=1;i<=n;i++) printf("%d ",lef[i]); 87 } 88 return 0; 89 }