在二分图匹配中有最大匹配问题,使用匈牙利算法或者网络流相关算法解决,如果给每条边增加一个权值,求权值和最大的匹配方案就叫做最大权匹配问题。其实之前所说的最大匹配就是权值为1的最大权匹配。

  求最大权完备匹配常用的方法是Kuhn-Munkres算法(简称KM算法),其主要思想就是通过顶标将求最大权匹配问题转化为求解最大匹配问题。算法的大致思路是任意构造一个可行顶标(比如Y结点顶标为0,X结点的顶标为它出发所有边的最大权值),然后求相等子图的最大匹配,如果存在完美匹配,算法终止,否则修改顶标使得相等子图的边变多,有更大的机会存在完美匹配。

  下面以题为例,给出时间复杂度O(n4)的算法。

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=3722

 /*
问题
将任意的两个字符串进行匹配,使得匹配后权值和最大 解题思路
将任意的字符串的权值计算出来,使用KM算法即可。
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; const int maxn=;
int W[maxn][maxn],n;
char s[maxn][];
int lx[maxn],ly[maxn];
int left[maxn];
bool S[maxn],T[maxn];
int len[maxn]; void presolve();
int KM();
bool match(int i);
void update(); int main()
{
int i,j;
while(scanf("%d",&n) != EOF)
{
for(i=;i<=n;i++)
{
scanf("%s",s[i]);
len[i]=strlen(s[i]);
}
presolve(); printf("%d\n",KM());
}
} bool match(int i)
{
S[i]=true;
for(int j=;j<=n;j++) if(lx[i]+ly[j] == W[i][j] && !T[j]){
T[j]=true;
if(!left[j] || match(left[j])){
left[j]=i;
return true;
}
}
return false;
} void update()
{
int a= <<;
for(int i=; i<=n; i++){
if(S[i]){
for(int j=;j<=n;j++){
if(!T[j]){
a = min(a,lx[i]+ly[j] - W[i][j]);
}
}
}
} for(int i=;i<=n;i++){
if(S[i]) lx[i] -= a;
if(T[i]) ly[i] += a;
}
} int KM()
{
for(int i=;i<=n;i++){
left[i] = lx[i] = ly[i] = ;
for(int j=; j<=n; j++)
lx[i]=max(lx[i],W[i][j]);
} for(int i=; i<=n; i++){
for(;;){
for(int j=;j<=n;j++){
S[j]=T[j]=;
}
if(match(i)) break;
else update();
}
} int ans=;
for(int i=;i<=n;i++)
ans += W[left[i]][i];
return ans;
} void presolve()
{
int i,j,k,p1,p2,cnt;
for(i=;i<=n;i++)
{
for(j=;j<=n;j++)
{
if(i==j)
{
W[i][j]=;
continue ;
} cnt=;
p1=len[i]-;
p2=;
while()
{
if(s[i][p1]==s[j][p2]) cnt++;
else break ;
p1--,p2++;
if(p1< || p2>=len[j]) break ;
}
W[i][j]=cnt;
}
}
}

KM算法及其应用的更多相关文章

  1. 匈牙利算法与KM算法

    匈牙利算法 var i,j,k,l,n,m,v,mm,ans:longint; a:..,..]of longint; p,f:..]of longint; function xyl(x,y:long ...

  2. 【HDU2255】奔小康赚大钱-KM算法

    Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem Description ...

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

    二分图最大权值匹配问题.用KM算法. 最小权值的时候把权值设置成相反数 /*-------------------------------------------------------------- ...

  4. KM算法及其优化的学习笔记&&bzoj2539: [Ctsc2000]丘比特的烦恼

    感谢  http://www.cnblogs.com/vongang/archive/2012/04/28/2475731.html 这篇blog里提供了3个链接……基本上很明白地把KM算法是啥讲清楚 ...

  5. poj 2195 KM算法

    题目链接:http://poj.org/problem?id=2195 KM算法模板~ 代码如下: #include "stdio.h" #include "string ...

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

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2255 题意:有N个人跟N个房子,每个人跟房子都有一定的距离,现在要让这N个人全部回到N个房子里面去,要 ...

  7. HDU(2255),KM算法,最大权匹配

    题目链接 奔小康赚大钱 Time Limit: 1000/1000MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  8. 二分图 最大权匹配 km算法

    这个算法的本质还是不断的找增广路: KM算法的正确性基于以下定理:若由二分图中所有满足A[i]+B[j]=w[i,j]的边(i,j)构成的子图(称做相等子图)有完备匹配,那么这个完备匹配就是二分图的最 ...

  9. hdu 2255 奔小康赚大钱 KM算法

    看到这么奇葩的题目名我笑了,后来这么一个裸的KM调了2小时我哭了…… 这是个裸的KM算法,也没什么多说的,主要是注意多组数据时,每次都要把各种数组清空啊,赋值啊什么的,反正比较麻烦.至于为什么调了2小 ...

  10. hdu 2853 Assignment KM算法

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2853 Last year a terrible earthquake attacked Sichuan ...

随机推荐

  1. c++ stl源码剖析学习笔记(三)容器 vector

    stl中容器有很多种 最简单的应该算是vector 一个空间连续的数组 他的构造函数有多个 以其中 template<typename T> vector(size_type n,cons ...

  2. Html5学习笔记:图片上传

    图片上传是业务需求中常见的功能,最基础的是单图片的上传.比较复杂的多图片上传,都是基于单图片上传. Form表单上传 h5的原生表单上传图片,代码如下: <!DOCTYPE html> & ...

  3. Android Studio导入第三方jar包或依赖工程的方法

    Android Studio导入第三方jar包或依赖工程的方法   一 导入jar包的方法 1.打开自己的工程,将需要导入的jar包copy到libs文件夹下 2.在导入的jar包处单击菜单 Add ...

  4. SQL笔试基础

    SQLSERVER服务器中,给定表table1 中有两个字段 ID.LastUpdateDate,ID表示更新的事务号,LastUpdateDate表示更新时的服务器时间,请使用一句SQL语句获得最后 ...

  5. ios 导航push跳转方向设置

    CATransition* transition = [CATransition animation]; transition.type = kCATransitionPush;//可更改为其他方式 ...

  6. crontab定时时间解释

    用户所建立的crontab文件中,每一行都代表一项任务,每行的每个字段代表一项设置,它的格式共分为六个字段,前五段是时间设定段,第六段是要执行的命令段,格式如下: minute hour day mo ...

  7. Angularjs自定义指令计算浏览器高度

    <!DOCTYPE html> <html ng-app="app"> <head> <title>柳絮飞祭奠</title& ...

  8. python中global和nonlocal用法的详细说明

    一.global 1.global关键字用来在函数或其他局部作用域中使用全局变量.但是如果不修改全局变量也可以不使用global关键字.   gcount = 0 def global_test(): ...

  9. Linux 根据PID找到相应应用程序的运行目录

    1.找到运行程序的PID # ps aux | grep redis root pts/ S+ : : grep redis root ? Ssl Aug30 : redis-server *: # ...

  10. POJ - 3984 迷宫问题 dfs解法

    #include<stdio.h> #include<string.h> #include<stack> #include<algorithm> usi ...