KM算法挺好的, 《训练手册》349页上讲解很详细。
const int maxn = 108 ;
double w[maxn][maxn] ;
double lx[maxn] , ly[maxn] ;
int Left[maxn] ;
bool S[maxn] , T[maxn] ;
int n ;
bool match(int i){
S[i] = 1 ;
for(int j = 1 ; j <= n ; j++){
if(!T[j] && fabs( lx[i] + ly[j] - w[i][j] ) < 1e-6){
T[j] = 1 ;
if(! Left[j] || match(Left[j]) ){
Left[j] = i ;
return 1 ;
}
}
}
return 0 ;
}
void update(){
double a = 1<<30 ;
for(int i = 1 ; i <= n ; i++){
if(S[i]){
for(int j = 1 ; j <= n ; j++){
if(! T[j])
a = min(a , lx[i] + ly[j] - w[i][j]) ;
}
}
}
for(int i = 1 ; i <= n ; i++){
if(S[i]) lx[i] -= a ;
if(T[i]) ly[i] += a ;
}
}
int km(){
for(int i = 1 ; i <= n ; i++){
Left[i] = lx[i] = ly[i] = 0 ;
for(int j = 1 ; j <= n ; j++)
lx[i] = max(lx[i] , w[i][j]) ;
}
for(int i = 1 ; i <= n ; i++){
while(1){
for(int j = 1 ; j <= n ; j++)
S[j] = T[j] = 0 ;
if(match(i)) break ;
else update() ;
}
}
int s = 0 ;
for(int i = 1 ; i <= n ; i++) s += w[Left[i]][i] ;
return s ;
}
int ax[maxn] , ay[maxn] ;
int bx[maxn] , by[maxn] ;
int ans[maxn] ;
int main(){
int i , j ;
cin>>n ;
for(i = 1 ; i <= n ; i++) scanf("%d%d" ,&ax[i] , &ay[i]) ;
for(i = 1 ; i <= n ; i++) scanf("%d%d" ,&bx[i] , &by[i]) ;
for(i = 1 ; i <= n ; i++){
for(j = 1 ; j <= n ; j++)
w[i][j] = -sqrt(0.0 + (ax[i] - bx[j])*(ax[i] - bx[j]) + (ay[i] - by[j])*(ay[i] - by[j]) );
}
km() ;
for(i = 1 ; i <= n ; i++) ans[Left[i]] = i ;
for(i = 1 ; i <= n ; i++) printf("%d\n" , ans[i]) ;
return 0 ;
}