您的位置:首页 > 其它

LA 4043 最优匹配

2017-05-01 21:37 169 查看
题目链接:https://vjudge.net/contest/161820#problem/A

题意: n 个 白点,n 个黑点,给出了坐标,求完美匹配后,各点不相交,输出白点对于的黑点编号;(输出输错了 (;´д`)ゞ)

分析:(a1-b1) (a2-b2)

#include <bits/stdc++.h>

using namespace std;
#define esp 1e-10
const double inf = 1e20;
const int maxn = 1000;
int n;
double W[maxn][maxn];
double Lx[maxn],Ly[maxn];
int lefts[maxn];
bool S[maxn],T[maxn];

bool match(int i) {
S[i] = true;
for(int j=1;j<=n;j++)
{
if(fabs(Lx[i]+Ly[j]-W[i][j])<esp&&!T[j]) {
T[j] = true;
if(!lefts[j]||match(lefts[j])) {
lefts[j] = i;
return true;
}
}
}
return false;
}

void update() {
double a = inf;
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;
}
}

void KM() {
for(int i=1;i<=n;i++) {
lefts[i] =0;
Ly[i] = 0;
Lx[i] = -inf;
for(int j=1;j<=n;j++) {
Lx[i] = max(Lx[i],W[i][j]);
}
}

for(int i=1;i<=n;i++) {
for(;;) {
for(int j=1;j<=n;j++)
S[j] = T[j] = 0;
if(match(i))
break;
else update();
}
}
}

struct Point {
double x,y;
}points[maxn];

int main()
{
while(scanf("%d",&n)!=EOF) {
for(int i=1;i<=2*n;i++)
scanf("%lf%lf",&points[i].x,&points[i].y);

for(int i=1;i<=n;i++) {
double x1 = points[i].x;
double y1 = points[i].y;

for(int j=n+1;j<=2*n;j++) {
double x2 = points[j].x;
double y2 = points[j].y;
W[j-n][i] = -sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
}

KM();

for(int i=1;i<=n;i++)
printf("%d\n",lefts[i]);

}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: