zoukankan      html  css  js  c++  java
  • 二分匹配之最大权值匹配算法---KM模板

    百科:http://baike.baidu.com/link?url=vbM3H4XmfrsWfP-epdlR2sVKSNzOq4hXnWDqm5uo8fd7VWsF2SmhDV35XyVUDvVjvrtf42RUITJuNCHn-7_x6K

    大神总结:http://www.cnblogs.com/skyming/archive/2012/02/18/2356919.html

    代码:

     1 #include<stdio.h>
     2 #include<string.h>
     3 const int N=555,INF=0x3f3f3f3f;
     4 int lx[N],ly[N],vx[N],vy[N],slack[N],match[N];
     5 int a[N][N];
     6 int nx,ny;
     7 int dfs(int u)
     8 {
     9     vx[u]=1;
    10     for(int i=1;i<=ny;i++)
    11     {
    12         if(vy[i])    continue;
    13         int t=lx[u]+ly[i]-a[u][i];
    14         if(t==0)
    15         {
    16             vy[i]=1;
    17             if(match[i]==-1||dfs(match[i]))
    18             {
    19                 match[i]=u;
    20                 return 1;
    21             }
    22         }
    23         else if(slack[i]>t)
    24             slack[i]=t;
    25     }
    26     return 0;
    27 }
    28 int KM()
    29 {
    30     int i,j,d;
    31     memset(ly,0,sizeof(ly));
    32     memset(match,-1,sizeof(match));
    33     for(i=1,lx[i]=-INF;i<=nx;i++)
    34         for(j=1;j<=ny;j++)
    35             if(a[i][j]>lx[i])
    36                 lx[i]=a[i][j];
    37     for(i=1;i<=nx;i++)
    38     {
    39         memset(slack,0x3f,sizeof(slack));
    40         while(1)
    41         {
    42             memset(vx,0,sizeof(vx));
    43             memset(vy,0,sizeof(vy));
    44             if(dfs(i))    break;
    45             d=INF;
    46             for(j=1;j<=ny;j++)
    47                 if(!vy[j]&&slack[j]<d)
    48                     d=slack[j];
    49             //if(d==INF)    break;//该点找不到任何匹配 
    50             for(j=1;j<=nx;j++)
    51                 if(vx[j])
    52                     lx[j]-=d;
    53             for(j=1;j<=ny;j++)
    54             {
    55                 if(vy[j])
    56                     ly[j]+=d;
    57                 else
    58                     slack[j]-=d;
    59             }
    60         }
    61     }
    62     int ans=0,sum=0;
    63     for(i=1;i<=ny;i++)
    64         if(match[i]>-1&&a[match[i]][i])
    65             ans+=a[match[i]][i],sum++; 
    66     printf("%d++
    ",sum);//匹配数 
    67     return ans;
    68 }
    69 int main()
    70 {
    71     int m,u,v,w,n,i;
    72     scanf("%d",&nx);
    73     scanf("%d",&ny);
    74     scanf("%d",&m);
    75     memset(a,0,sizeof(a));
    76     while(m--)
    77     {
    78         scanf("%d%d%d",&u,&v,&w);
    79         a[u][v]=a[v][u]=w;
    80     }
    81     printf("%d
    ",KM());
    82     return 0;
    83 }
  • 相关阅读:
    免密码远程登录和远程操作
    1、linux网络服务实验 用PuTTY连接Linux
    巧用CAS解决数据一致性问题
    第一天
    图像处理02
    图像处理01
    Poem 01(转)
    CS229 Lecture 01
    日本語1
    latex测试
  • 原文地址:https://www.cnblogs.com/L-King/p/5519927.html
Copyright © 2011-2022 走看看