zoukankan      html  css  js  c++  java
  • LA 4043 最优匹配

    题目链接:https://vjudge.net/contest/161820#problem/A

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

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

    如果这样连接,那么肯定大于 (a1-b2) (a2-b1);也就说,我们要的完美匹配要是权值最小的匹配;

    这样,我们的权值,可以全改为负数,这样就可以转为普通的KM算法了;

    KM算法(我的理解):

      可行标  lx(i) + ly(j)>=w(i,j),当完全子图中的 所有lx(i) + ly(j) ==w(i,j) 时,就有,这个子图是最大权匹配的完美匹配(最佳完美匹配);

      怎么得到可行标呢? 初始化话所有X是邻接阵里面最大的那一条,然后在匈牙利树上找,不断的扩充这个匈牙利树,直到成为一个完全子图;

      怎么扩充匈牙利树呢? 每次在S,T' 中找最小的一个lx(x) + ly(y) -w(x,y),去修改原来的匈牙利树,使得有可能有新的边加进来;

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 #define esp 1e-10
     5 const double inf = 1e20;
     6 const int maxn = 1000;
     7 int n;
     8 double W[maxn][maxn];
     9 double Lx[maxn],Ly[maxn];
    10 int lefts[maxn];
    11 bool S[maxn],T[maxn];
    12 
    13 
    14 bool match(int i) {
    15     S[i] = true;
    16     for(int j=1;j<=n;j++)
    17     {
    18         if(fabs(Lx[i]+Ly[j]-W[i][j])<esp&&!T[j]) {
    19             T[j] = true;
    20             if(!lefts[j]||match(lefts[j])) {
    21                 lefts[j] = i;
    22                 return true;
    23             }
    24         }
    25     }
    26     return false;
    27 }
    28 
    29 void update() {
    30     double a = inf;
    31     for(int i=1;i<=n;i++) if(S[i])
    32         for(int j=1;j<=n;j++) if(!T[j])
    33             a = min(a,Lx[i]+Ly[j]-W[i][j]);
    34 
    35     for(int i=1;i<=n;i++) {
    36         if(S[i]) Lx[i]-=a;
    37         if(T[i]) Ly[i]+=a;
    38     }
    39 }
    40 
    41 void KM() {
    42     for(int i=1;i<=n;i++) {
    43         lefts[i] =0;
    44         Ly[i] = 0;
    45         Lx[i] = -inf;
    46         for(int j=1;j<=n;j++) {
    47             Lx[i] = max(Lx[i],W[i][j]);
    48         }
    49     }
    50 
    51     for(int i=1;i<=n;i++) {
    52         for(;;) {
    53             for(int j=1;j<=n;j++)
    54                 S[j] = T[j] = 0;
    55             if(match(i))
    56                 break;
    57             else update();
    58         }
    59     }
    60 }
    61 
    62 struct Point {
    63     double x,y;
    64 }points[maxn];
    65 
    66 
    67 int main()
    68 {
    69     while(scanf("%d",&n)!=EOF) {
    70         for(int i=1;i<=2*n;i++)
    71             scanf("%lf%lf",&points[i].x,&points[i].y);
    72 
    73         for(int i=1;i<=n;i++) {
    74             double x1 = points[i].x;
    75             double y1 = points[i].y;
    76 
    77             for(int j=n+1;j<=2*n;j++) {
    78                 double x2 = points[j].x;
    79                 double y2 = points[j].y;
    80                 W[j-n][i] = -sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
    81             }
    82         }
    83 
    84         KM();
    85 
    86         for(int i=1;i<=n;i++)
    87             printf("%d
    ",lefts[i]);
    88 
    89     }
    90     return 0;
    91 }
    View Code
  • 相关阅读:
    visualSVNYou don't have permission to access on this server
    怎样截取Http请求
    ASP.NET @page 指令详解
    我的XMLHelperC# XML操作基类(修改,删除,新增,创建)
    最新Visual Studio 2010 下载及学习资料
    redis主从哨兵和集群的区别
    uniapp nvue 支持iconfont
    Error (Error Code: 1175) during executing update command on table using MySQL
    org.apache.jasper.JasperException: Unable to compile class for JSP
    java.sql.SQLException: Access denied for user 'root'@'10.10.10.10' (using password: YES)
  • 原文地址:https://www.cnblogs.com/TreeDream/p/6793013.html
Copyright © 2011-2022 走看看