zoukankan      html  css  js  c++  java
  • {KM}

     

    update(2018-01-20):

    发现暑假的时候真是zz。。。

    学了好久也不是很理解,今天一下就看懂了。。。

    之前还以为不用slack的方法更快,理解了之后发现没用slack数组的写法都是错的orz。。。很巧合的过了一些题。。。zz



     

    Ants

     UVALive - 4043 

    这题真是心态崩了

    一开始犯了一个致命的错误始终没发现,WA了十几发完全无解

    索性重新写了一遍,结果一直TLE,一共交了将近30发

    早上起来试着加上slack数组,结果过了。。。

    之前一直觉得slack数组没什么用的,竟然会超时。。。

    然后忽然也发现了昨天那个错误。。。

    本来很简单的一道题。。。orz心态崩了

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const double inf=1e30;
     4 const int maxv=110;
     5 double c[maxv][maxv];
     6 int vb[maxv],vg[maxv];
     7 double eb[maxv],eg[maxv];
     8 int mc[maxv];
     9 double d;
    10 int n;
    11 int ll[maxv];
    12 struct node
    13 {
    14     int x,y;
    15 }b[maxv],w[maxv];
    16 double getdis(int i,int j)
    17 {
    18     int dx=b[i].x-w[i].x;
    19     int dy=b[i].y-w[i].y;
    20     return sqrt(dx*dx+dy*dy);
    21 }
    22 bool eq(double a,double b)
    23 {
    24     return  fabs(a-b)<1e-9;
    25 }
    26 int dfs(int x)
    27 {
    28     vg[x]=1;
    29     for(int i=0;i<n;i++)
    30     {
    31         if(vb[i]) continue;
    32        
    33         double gap=eg[x]+eb[i]-c[x][i];
    34         if(eq(gap,0))
    35         {
    36              vb[i]=1;
    37             if(mc[i]==-1||dfs(mc[i]))
    38             {
    39                 ll[x]=i;
    40                 mc[i]=x;
    41                 return 1;
    42             }
    43         }
    44         else d=min(d,gap);
    45     }
    46     return 0;
    47 }
    48 void KM()
    49 {
    50     memset(mc,-1,sizeof(mc));
    51     memset(eb,0,sizeof(eb));
    52     for(int i=0;i<n;i++)
    53     {
    54         eg[i]=c[i][0];
    55         for(int j=1;j<n;j++)
    56             eg[i]=max(eg[i],c[i][j]);
    57     }
    58 
    59     for(int i=0;i<n;i++)
    60     {
    61         while(1)
    62         {
    63             memset(vb,0,sizeof(vb));
    64             memset(vg,0,sizeof(vg));
    65             d=inf;
    66         
    67             if(dfs(i)) break;
    68             for(int i=0;i<n;i++)
    69             {
    70                 if(vb[i]) eb[i]+=d;
    71                 if(vg[i]) eg[i]-=d;
    72             }
    73         }
    74     }
    75 }
    76 int main()
    77 {
    78     int kase=0;
    79     while(scanf("%d",&n)!=EOF)
    80     {
    81         for(int i=0;i<n;i++)
    82             scanf("%d%d",&b[i].x,&b[i].y);
    83         for(int i=0;i<n;i++)
    84             scanf("%d%d",&w[i].x,&w[i].y);
    85         for(int i=0;i<n;i++)
    86             for(int j=0;j<n;j++)
    87             c[i][j]=-getdis(i,j);
    88         KM();
    89       //  if(kase++) puts("");
    90         for(int i=0;i<n;i++) printf("%d
    ",ll[i]+1);
    91     }
    92 
    93 }
    deadly版
     1 #include <bits/stdc++.h>
     2 using namespace  std;
     3 const int maxv=210;
     4 int n;
     5 struct node
     6 {
     7     int x,y;
     8 }a[maxv],b[maxv];
     9 
    10 double c[maxv][maxv];
    11 double eg[maxv],eb[maxv];
    12 int vb[maxv],vg[maxv];
    13 int mc[maxv];
    14 double d;
    15 
    16 bool eq(double x,double y)
    17 {
    18     return fabs(x-y)<1e-10;
    19 }
    20 int dfs(int x)
    21 {
    22     vg[x]=1;
    23     for(int i=0;i<n;i++)
    24     {
    25         if(vb[i]) continue;
    26         if(eq(eg[x]+eb[i],c[x][i]))
    27         {
    28             vb[i]=1;
    29             if(mc[i]==-1||dfs(mc[i]))
    30             {
    31                 mc[i]=x;
    32                 return 1;
    33             }
    34         }
    35         else d=min(d,eg[x]+eb[i]-c[x][i]);
    36     }
    37     return 0;
    38 }
    39 void KM()
    40 {
    41     memset(mc,-1,sizeof(mc));
    42     memset(eb,0,sizeof(eb));
    43     for(int i=0;i<n;i++)
    44     {
    45         eg[i]=c[i][0];
    46         for(int j=1;j<n;j++)
    47             eg[i]=max(eg[i],c[i][j]);
    48     }
    49     for(int i=0;i<n;i++)
    50     {
    51         while(1)
    52         {
    53             memset(vb,0,sizeof(vb));
    54             memset(vg,0,sizeof(vg));
    55             d=1e20;
    56             if(dfs(i)) break;
    57             for(int i=0;i<n;i++)
    58             {
    59                 if(vb[i]) eb[i]+=d;
    60                 if(vg[i]) eg[i]-=d;
    61             }
    62         }
    63     }
    64 }
    65 
    66 int main()
    67 {
    68     while(scanf("%d",&n)!=EOF)
    69     {
    70         for(int i=0;i<n;i++) scanf("%d%d",&b[i].x,&b[i].y);
    71         for(int i=0;i<n;i++) scanf("%d%d",&a[i].x,&a[i].y);
    72         for(int i=0;i<n;i++)
    73             for(int j=0;j<n;j++)
    74         {
    75             double x=a[i].x-b[j].x;
    76             double y=a[i].y-b[j].y;
    77             c[i][j]=-sqrt(x*x+y*y);
    78         }
    79         KM();
    80         for(int i=0;i<n;i++)
    81             printf("%d
    ",mc[i]+1);
    82     }
    83 }
    无slack超时版
     1 #include <bits/stdc++.h>
     2 using namespace  std;
     3 const double inf=1e20;
     4 const int maxv=210;
     5 int n;
     6 struct node
     7 {
     8     int x,y;
     9 }a[maxv],b[maxv];
    10 
    11 double c[maxv][maxv];
    12 double eg[maxv],eb[maxv];
    13 int vb[maxv],vg[maxv];
    14 int mc[maxv];
    15 double slack[maxv];
    16 
    17 bool eq(double x,double y)
    18 {
    19     return fabs(x-y)<1e-10;
    20 }
    21 
    22 int dfs(int x)
    23 {
    24     vg[x]=1;
    25     for(int i=0;i<n;i++)
    26     {
    27         if(vb[i]) continue;
    28         if(eq(eg[x]+eb[i],c[x][i]))
    29         {
    30             vb[i]=1;
    31             if(mc[i]==-1||dfs(mc[i]))
    32             {
    33                 mc[i]=x;
    34                 return 1;
    35             }
    36         }
    37         else slack[i]=min(slack[i],eg[x]+eb[i]-c[x][i]);
    38     }
    39     return 0;
    40 }
    41 void KM()
    42 {
    43     memset(mc,-1,sizeof(mc));
    44     memset(eb,0,sizeof(eb));
    45     for(int i=0;i<n;i++)
    46     {
    47         eg[i]=c[i][0];
    48         for(int j=1;j<n;j++)
    49             eg[i]=max(eg[i],c[i][j]);
    50     }
    51     for(int i=0;i<n;i++)
    52     {
    53         for(int i=0;i<n;i++) slack[i]=inf;
    54         while(1)
    55         {
    56             memset(vb,0,sizeof(vb));
    57             memset(vg,0,sizeof(vg));
    58             if(dfs(i)) break;
    59             double d=1e20;
    60             for(int i=0;i<n;i++) if(!vb[i]) d=min(d,slack[i]);
    61             for(int i=0;i<n;i++)
    62             {
    63                 if(vg[i]) eg[i]-=d;
    64                 if(vb[i]) eb[i]+=d;
    65                 else slack[i]-=d;
    66             }
    67         }
    68     }
    69 }
    70 
    71 int main()
    72 {
    73     while(scanf("%d",&n)!=EOF&&n)
    74     {
    75         for(int i=0;i<n;i++) scanf("%d%d",&b[i].x,&b[i].y);
    76         for(int i=0;i<n;i++) scanf("%d%d",&a[i].x,&a[i].y);
    77         for(int i=0;i<n;i++)
    78             for(int j=0;j<n;j++)
    79         {
    80             double x=a[i].x-b[j].x;
    81             double y=a[i].y-b[j].y;
    82             c[i][j]=-sqrt(x*x+y*y);
    83         }
    84         KM();
    85         for(int i=0;i<n;i++)
    86             printf("%d
    ",mc[i]+1);
    87     }
    88 }
    View Code

    Golden Tiger Claw

     UVA - 11383 

    KM算法的副产品

    KM之后,所有顶标之和是最小的

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define CLR(m,a) memset(m,a,sizeof(m))
     4 const int inf=0x3f3f3f3f;
     5 const int maxv=510;
     6 int n;
     7 int vb[maxv],vg[maxv],eb[maxv],eg[maxv];
     8 int mc[maxv];
     9 int slack[maxv];
    10 int c[maxv][maxv];
    11 
    12 int dfs(int x)
    13 {
    14     vg[x]=1;
    15     for(int i=0;i<n;i++)
    16     {
    17         if(vb[i]) continue;
    18         int gap=eg[x]+eb[i]-c[x][i];
    19         if(gap==0)
    20         {
    21             vb[i]=1;
    22             if(mc[i]==-1||dfs(mc[i]))
    23             {
    24                 mc[i]=x;
    25                 return 1;
    26             }
    27         }
    28         else slack[i]=min(slack[i],gap);
    29     }
    30     return 0;
    31 }
    32 
    33 void KM()
    34 {
    35     CLR(mc,-1);
    36     CLR(eb,0);
    37     for(int i=0;i<n;i++)
    38     {
    39         eg[i]=c[i][0];
    40         for(int j=1;j<n;j++)
    41             eg[i]=max(eg[i],c[i][j]);
    42     }
    43     for(int i=0;i<n;i++)
    44     {
    45         CLR(slack,inf);
    46         while(1)
    47         {
    48             CLR(vb,0);
    49             CLR(vg,0);
    50             if(dfs(i)) break;
    51             int d=inf;
    52             for(int i=0;i<n;i++) if(!vb[i]) d=min(d,slack[i]);
    53             for(int i=0;i<n;i++)
    54             {
    55                 if(vg[i]) eg[i]-=d;
    56                 if(vb[i]) eb[i]+=d;
    57             }
    58         }
    59     }
    60 }
    61 int main()
    62 {
    63     while(scanf("%d",&n)!=EOF)
    64     {
    65         for(int i=0;i<n;i++)
    66             for(int j=0;j<n;j++)
    67                 scanf("%d",&c[i][j]);
    68         KM();
    69         int ans=0;
    70         for(int i=0;i<n;i++)
    71             ans+=eg[i]+eb[i];
    72         for(int i=0;i<n-1;i++)
    73             printf("%d ",eg[i]);
    74         printf("%d
    ",eg[n-1]);
    75         for(int i=0;i<n-1;i++)
    76             printf("%d ",eb[i]);
    77         printf("%d
    ",eb[n-1]);
    78         printf("%d
    ",ans);
    79     }
    80 
    81 }
    View Code
  • 相关阅读:
    面向对象(二)-特性
    面向对象(一)-初步认识
    函数(十)-内置模块
    函数(九)-包与模块
    函数(八)-闭包与装饰器
    函数(七)-嵌套作用域
    函数(六)-匿名函数
    CSS阴影效果(Box-shadow)用法趣味讲解
    css 实现div内显示两行或三行,超出部分用省略号显示
    js基础知识(一)--截取字符串
  • 原文地址:https://www.cnblogs.com/yijiull/p/7227754.html
Copyright © 2011-2022 走看看