zoukankan      html  css  js  c++  java
  • LA4043二分图最佳匹配(注意建模)

     1 /*LA4043
     2 1<=n<=100
     3 给定两个集合A,B,每个集合的n个元素的坐标,以欧几里得距离为权值。
     4 求一个A到B的一一映射,每一对相互连线,使得,没有任何两条线是相交的。
     5 
     6 这道题有个特解:A和B的最佳匹配(使负的权值和最大),因为两条交叉的线,能换成两条不交叉的,从而增大负权值和。
     7 */
     8 #include <cmath>
     9 #include <algorithm>
    10 #include <stdlib.h>
    11 #include <iostream>
    12 #include <string.h>
    13 #include <stdio.h>
    14 #include <stack>
    15 #include <set>
    16 #include <map>
    17 #include <vector>
    18 #define typed double
    19 #define INF 1<<30
    20 #define maxn 110
    21 #define eps 1e-6
    22 using namespace std;
    23 int n;
    24 typed W[maxn][maxn];
    25 typed Lx[maxn],Ly[maxn];
    26 int lef[maxn];
    27 bool S[maxn],T[maxn];
    28 
    29 bool match(int i){
    30     S[i]=true;
    31     for(int j=1;j<=n;j++) if (fabs(Lx[i]+Ly[j]-W[i][j])<eps && !T[j]){
    32         T[j]=true;
    33         if (!lef[j] || match(lef[j])){
    34             lef[j]=i;
    35             return true;
    36         }
    37     }
    38     return false;
    39 }
    40 
    41 void update(){
    42     typed a=INF;
    43     for(int i=1;i<=n;i++) if(S[i]){
    44         for(int j=1;j<=n;j++) if(!T[j])
    45             a=min(a,Lx[i]+Ly[j]-W[i][j]);
    46     }
    47     for(int i=1;i<=n;i++){
    48         if (S[i]) Lx[i]-=a;
    49         if (T[i]) Ly[i]+=a;
    50     }
    51 }
    52 void KM(){
    53     for(int i=1;i<=n;i++){
    54         lef[i]=Lx[i]=Ly[i]=0;
    55         for(int j=1;j<=n;j++){
    56             Lx[i]=max(Lx[i],W[i][j]);
    57         }
    58     }
    59     for(int i=1;i<=n;i++){
    60         for(;;){
    61             for(int j=1;j<=n;j++) S[j]=T[j]=false;
    62             if (match(i)) break;else update();
    63         }
    64     }
    65 }
    66 typed AX[maxn],AY[maxn];
    67 typed BX[maxn],BY[maxn];
    68 double dis(int u,int v){
    69     double ans=-sqrt((BX[u]-AX[v])*(BX[u]-AX[v])+(BY[u]-AY[v])*(BY[u]-AY[v]));
    70     return ans;
    71 }
    72 void read(){
    73     for(int i=1;i<=n;i++) scanf("%lf%lf",&AX[i],&AY[i]);
    74     for(int i=1;i<=n;i++) scanf("%lf%lf",&BX[i],&BY[i]);
    75     for(int i=1;i<=n;i++)
    76     for(int j=1;j<=n;j++)
    77     W[i][j]=dis(i,j);
    78 }
    79 int t=0;
    80 int main(){
    81     while(cin>>n){
    82         t++;
    83         read();
    84         KM();
    85         if (t>1) printf("
    ");
    86         for(int i=1;i<=n;i++) printf("%d
    ",lef[i]);
    87     }
    88     return 0;
    89 }
  • 相关阅读:
    JS之四舍五入有小数点
    c# table 怎么在前台循环展示 ViewBag
    c# ajax从后台获取数据list数组 $.each再显示数据
    c# 快捷键
    c#_导出table功能
    c# 缓存详解
    c# url链接转成二维码图片,再转成byte[]二进制流,输出到前段ajax
    JS ajax 返回的json对象 新增属性值(干货)
    tomcat配置HTTPS
    zookeeper集群安装
  • 原文地址:https://www.cnblogs.com/little-w/p/3643969.html
Copyright © 2011-2022 走看看