二分匹配之最大权值匹配算法---KM模板

Posted L&King

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二分匹配之最大权值匹配算法---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++\\n",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\\n",KM());
82     return 0;
83 }

 

以上是关于二分匹配之最大权值匹配算法---KM模板的主要内容,如果未能解决你的问题,请参考以下文章

hdu 2255奔小康赚大钱 KM算法模板

二分图 模板

HDU2255-奔小康赚大钱-二分图最大权值匹配-KM算法

HDU 2255 KM算法 二分图最大权值匹配

二分图最大权完美匹配KM算法模板

二分图'最佳匹配' KM算法