LA4043

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;


#define maxn 110
#define esp 1e-8
double inf=1000000.0;
double dis(double x1,double y1,double x2,double y2)
{
       return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}


bool dayu(double a,double b)
{
     return a-esp>b;
}
double lx[maxn],ly[maxn];
bool visx[maxn],visy[maxn];
double w[maxn][maxn];
double slack[maxn];
int n,nx,ny;
double wx[maxn],wy[maxn];
double bx[maxn],by[maxn];
int match[maxn];
int match1[maxn];
bool dfs(int x)
{
     visx[x]=1;
     for(int y=1;y<=ny;y++)
     {
             if(!visy[y])
             {
                         double temp=lx[x]+ly[y]-w[x][y];
                         if(fabs(temp)<esp)
                         {
                                      visy[y]=1;
                                      if(match[y]==-1||dfs(match[y]))
                                      {
                                                                     match[y]=x;
                                                                     match1[x]=y;
                                                                     return true;
                                      }
                         }
                         else
                         {
                             if(dayu(slack[y],temp))
                             {
                                                    slack[y]=temp;
                             }
                         }
             }
             else continue;
     }
     return false;
}


void km()
{
    memset(match,-1,sizeof(match));
    memset(ly,0,sizeof(ly));
    for(int i=1;i<=nx;i++)
    {
            lx[i]=-inf;
            for(int j=1;j<=ny;j++)
            if(dayu(w[i][j],lx[i]))
            lx[i]=w[i][j];
    }
    
    
    for(int i=1;i<=n;i++)
    {
            for(int j=1;j<=ny;j++)slack[j]=inf;
            while(true)
            {
               memset(visx,0,sizeof(visx));
               memset(visy,0,sizeof(visy));
               
               if(dfs(i))break;
               
               double d=inf;
               for(int j=1;j<=ny;j++)
               if(!visy[j]&&dayu(d,slack[j]))
               d=slack[j];
               
               
               for(int j=1;j<=nx;j++)
               if(visx[j])lx[j]-=d;
               
               
               for(int j=1;j<=ny;j++)
               if(visy[j])ly[j]+=d;
               else slack[j]-=d;
            }
    }
    
    for(int i=1;i<=nx;i++)
          printf("%d\n",match1[i]);
}


int main()
{
    for(;scanf("%d",&n)==1;)
    {
        nx=ny=n;
        
        for(int i=1;i<=nx;i++)scanf("%lf%lf",&wx[i],&wy[i]);
        for(int i=1;i<=ny;i++)scanf("%lf%lf",&bx[i],&by[i]);
        for(int i=1;i<=nx;i++)
        for(int j=1;j<=ny;j++)
        w[i][j]=0.0-dis(wx[i],wy[i],bx[j],by[j]);
        km();
       // printf("\n");
    }
return 0;

}


//二分图

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值