zoukankan      html  css  js  c++  java
  • 最大权匹配KM算法模板

     Kuhn-Munkras算法流程:

      (1)初始化可行顶标的值

      (2)用匈牙利算法寻找完备匹配

      (3)若未找到完备匹配则修改可行顶标的值

      (4)重复(2)(3)直到找到相等子图的完备匹配为止

    直接附代码

     1 bool dfs(int x)//匈牙利算法寻找x的增广路径 以x为根的M的交错树 
     2 {
     3     int y,t;
     4     visx[x]=true;
     5     for(y=0;y<N;y++)
     6     {
     7         if(visy[y])    continue;//找增广路径的过程中不妨问已经访问过的顶点 
     8         t=lx[x]+ly[y]-g[x][y];//在相等子图中寻找匹配的增广路径
     9         if(t==0)
    10         {
    11             visy[y]=true;
    12             if(linky[y]==-1||dfs(linky[y]))
    13             {
    14                 linky[y]=x;
    15                 return true;
    16             }
    17         }
    18         else//因为本来就需要将一条x顶点在交错树中,y顶点不在交错树中的边扩展进交错树来
    19         //所以只改变这些不在等子图中的边的y顶点的松弛量 
    20         {
    21             if(slack[y]>t)
    22                 slack[y]=t;
    23         }
    24     }
    25     return false;
    26 }
    27 //外层的匈牙利算法需要O(2)的时间,而修改顶标时由于要枚举所有的边所以也需要O(2)的时间
    28 //所以总时间是O(4) 
    29 //引入松弛量以后改变顶标就不需要枚举每一条边,只需要枚举不在交错树中的y的松弛量,所以
    30 //时间复杂度降为O(3) 
    31 int KM()
    32 {
    33     int i,j,x,d,res=0;
    34     memset(linky,-1,sizeof(linky));
    35     memset(lx,0,sizeof(lx));//x的顶标
    36     memset(ly,0,sizeof(ly));//y的顶标
    37     for(i=0;i<N;i++)
    38         for(j=0;j<N;j++)
    39             if(g[i][j]>lx[i])
    40                 lx[i]=g[i][j];//一开始x的顶标为所有与x相连的边中权值最大的边的权值,y的顶标为0 
    41     for(x=0;x<N;x++)
    42         {//在匈牙利算法中从每个x出发寻找增广路,如果找到就在匹配值上加1,这是为了寻找最大匹配
    43         //而在此处,必须找到完备匹配,所以对于每一个x中的顶点,找到其增广路就跳出,找不到的话
    44         //就需要修改顶标值直至找到为止 
    45             for(i=0;i<N;i++)
    46                 slack[i]=INF;
    47             while(true)
    48             {//无限循环直至找到完备匹配 
    49                 memset(visx,false,sizeof(visx));
    50                 memset(visy,false,sizeof(visy));
    51                 if(dfs(x))break;
    52                 d=INF;
    53                 for(i=0;i<N;i++)
    54                 {
    55                     if(!visy[i]&&d>slack[i]))//注意是取所有不在交错树中的y顶点的松弛量的最小值作为d的值 
    56                             d=slack[i];
    57                 }
    58                 for(i=0;i<N;i++)
    59                     if(visx[i])  lx[i]-=d;
    60                 for(i=0;i<N;i++)
    61                     if(visy[i])  ly[i]+=d;
    62                     else slack[i]-=d;
    63             }
    64         }
    65     for(i=0;i<N;i++)
    66         if(linky[i]!=-1)    res+=g[linky[i]][i];
    67     return res;
    68 }

     plus:若要求最小权匹配,只需将所有边权值取反,同时让x的顶标能取到负值中的最大值。

  • 相关阅读:
    boot空间不足
    catkin init/build 遇到catkin:command not found 的解决办法。
    ros自定义消息的时候报错ImportError: No module named em
    Opencv——相机标定
    Spring Boot 怎么打一个可执行 Jar 包?
    代码写成这样,老夫无可奈何!
    在外包干了三年,我废了……不吹不黑!
    国庆加了三天班,公司不给钱,咋办?
    面试官问线程安全的List,看完再也不怕了!
    年轻人的第一个自定义 Spring Boot Starter!
  • 原文地址:https://www.cnblogs.com/-dante-/p/3269019.html
Copyright © 2011-2022 走看看