思路:由于最佳匹配不会存在相交情况、于是直接KM算法、由于是小数、注意精度误差、KM算法求的是最大权值和、所以将所有边变负、便可以求出最小权值和
自己写的第一道KM、、、、mark
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
#define eps 1e-4
struct node
{
double x,y;
}dot1[105],dot2[105];
int n;
double mpt[105][105];
int match[105];
double lx[105];
double ly[105];
bool visitx[105];
bool visity[105];
double dist(node a,node b)
{
return -sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int hungary(int x)
{
visitx[x]=true;
for(int i=1;i<=n;i++)
{
if(!visity[i]&&fabs(lx[x]+ly[i]-mpt[x][i])<eps)
{
visity[i]=true;
if(match[i]==-1||hungary(match[i]))
{
match[i]=x;
return 1;
}
}
}
return 0;
}
void KM_perfect_match()
{
memset(match,-1,sizeof(match));
memset(lx,0,sizeof(lx));
memset(ly,0,sizeof(ly));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
lx[i]=max(lx[i],mpt[i][j]);
for(int i=1;i<=n;i++)
{
while(1)
{
memset(visitx,false,sizeof(visitx));
memset(visity,false,sizeof(visity));
if(hungary(i))break;//匹配成功
else//匹配失败,找最小值
{
double temp=0x3f3f3f;
for(int j=1;j<=n;j++)
{
if(visitx[j])
{
for(int k=1;k<=n;k++)
{
if(!visity[k]&&temp>(lx[j]+ly[k]-mpt[j][k]))
temp=lx[j]+ly[k]-mpt[j][k];
}
}
}
for(int j=1;j<=n;j++)
{
if(visitx[j])
lx[j]-=temp;
if(visity[j])
ly[j]+=temp;
}
}
}
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lf%lf",&dot1[i].x,&dot1[i].y);
}
for(int i=1;i<=n;i++)
{
scanf("%lf%lf",&dot2[i].x,&dot2[i].y);
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
mpt[i][j]=dist(dot1[i],dot2[j]);
}
}
KM_perfect_match();
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(match[j]==i)
{
printf("%d\n",j);
break;
}
}
}
return 0;
}
POJ 3565 Ants (证明+KM算法),布布扣,bubuko.com
原文:http://blog.csdn.net/a1dark/article/details/24287667