KM 模板题
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;
const int MAXN = 107;
const int INF = 1<<27;
const double eps = 1e-6;
struct KM {
double dt[MAXN][MAXN];
double lx[MAXN], ly[MAXN], slack[MAXN];
int match[MAXN];
int n;
bool vx[MAXN], vy[MAXN];
void init(int n) { this->n = n;}
void add(int u, int v, double d) { dt[u][v] = d;}
bool dfs(int u) {
vx[u] = true;
double tmp;
for(int i = 1; i <= n; i++) {
if(vy[i]) continue;
tmp = lx[u] + ly[i] - dt[u][i];
if(tmp < eps) {
vy[i] = true;
if(match[i] == -1 || dfs(match[i]))
{
match[i] = u;
return true;
}
}
else slack[i] = min(slack[i], tmp);
}
return false;
}
void km() {
int i, j, k;
memset(match, -1, sizeof(match));
memset(ly, 0, sizeof(ly));
for(i = 1; i <= n; i++){
lx[i] = dt[i][1];
for(j = 2; j <= n; j++) lx[i] = max(lx[i], dt[i][j]);
}
for(k = 1; k <= n; k++) {
for(i = 1; i <= n; i++) slack[i] = INF;
while(true) {
memset(vx, 0, sizeof(vx));
memset(vy, 0, sizeof(vy));
if(dfs(k)) break;
double nmin = INF;
for(i = 1; i <= n; i++) {
if( !vy[i]) nmin = min(nmin, slack[i]);
}
for(i = 1; i <= n; i++) {
if(vx[i]) lx[i] -= nmin;
if(vy[i]) ly[i] += nmin;
else slack[i] -= nmin;
}
}
}
}
}km;
int x[2][MAXN], y[2][MAXN];
int link[MAXN];
double dist(int x1, int y1, int x2, int y2) {
return sqrt( (double)(x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) );
}
int main() {
int n, i, j;
while(~scanf("%d", &n)){
km.init(n);
for(i = 1; i <= n; i++) scanf("%d%d", &x[0][i], &y[0][i]);
for(i = 1; i <= n; i++) scanf("%d%d", &x[1][i], &y[1][i]);
for(i = 1; i <= n; i++) {
for(j = 1; j <= n; j++) {
km.add(i, j, -dist(x[0][i], y[0][i], x[1][j], y[1][j]));
}
}
km.km();
for(i = 1; i <= n; i++) {
for(j = 1; j <= n; j++) if(km.match[j] == i) {
printf("%d\n", j);
}
}
}
return 0;
}