• 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 }
  • 相关阅读:
    小村系列之十八:幸福的桥
    小村系列之十六:改革的石头
    获取<select>,<radio>,<checkbox>中未被选中的value值和被选中的value值
    display:inline-block,block,inline的区别与用法
    Java中List Set Map集合的遍历
    C#自定义List类
    C#获取文件和文件夹大小
    C# winform带进度条的图片下载
    C#委托的详细使用
    asp.net cookie和session的详细使用
  • 原文地址:https://www.cnblogs.com/little-w/p/3643969.html
Copyright © 2020-2023  润新知