hdu 2255二分图最大权值匹配的KM 算法
2014-02-06 20:45
411 查看
对KM的深入理解请看以下博客(写的不错的):http://blog.sina.com.cn/s/blog_691ce2b701016reh.html
我的理解:如有错误,请大牛指正!!
1.KM()算法实际就是一种遍历,从权值最大的开始匹配,如果成功的完备匹配了,那这个权值一定是最大的权值。因为我们是从最大的开始一点点小下来遍历的。
2.slack[ ] 这个数组 可以说是一个 松弛变量数组 ,目的是为了 增加匹配。
3.实际也没什么好讲的就是不断的增广,很多也都这样,松弛迫近,跟那什么单纯形法有想通之处。
4. 匈牙利算法进行匹配的寻找。
hdu 2255
我的理解:如有错误,请大牛指正!!
1.KM()算法实际就是一种遍历,从权值最大的开始匹配,如果成功的完备匹配了,那这个权值一定是最大的权值。因为我们是从最大的开始一点点小下来遍历的。
2.slack[ ] 这个数组 可以说是一个 松弛变量数组 ,目的是为了 增加匹配。
3.实际也没什么好讲的就是不断的增广,很多也都这样,松弛迫近,跟那什么单纯形法有想通之处。
4. 匈牙利算法进行匹配的寻找。
hdu 2255
#include<cstdio> #include<iostream> #include<cstring> using namespace std; const int M=400,inf=0x3f3f3f3f; int w[M][M],link[M],lx[M],ly[M]; int nx,ny,n,slack[M]; int visx[M],visy[M]; int DFS(int x){ visx[x]=1; int i; for(i=1;i<=ny;i++){ if(visy[i]) continue; int t=lx[x]+ly[i]-w[x][i]; if(t==0){ visy[i]=1; if(link[i]==-1||DFS(link[i])){ link[i]=x; return 1; } } else if(slack[i]>t) slack[i]=t; } return 0; } int KM() { int i,j; memset(link,-1,sizeof(link)); memset(ly,0,sizeof(ly)); for(i=1;i<=nx;i++) for(j=1,lx[i]=-inf;j<=ny;j++){ if(lx[i]<w[i][j]) lx[i]=w[i][j]; } for(i=1;i<=nx;i++){ for(j=1;j<=ny;j++) slack[j]=inf; while(1){ memset(visx,0,sizeof(visx)); memset(visy,0,sizeof(visy)); if(DFS(i)) break; int d=inf; for(j=1;j<=ny;j++) if(!visy[j]&&slack[j]<d) d=slack[j]; for(j=1;j<=nx;j++) if(visx[j]) lx[j]-=d; for(j=1;j<=ny;j++) if(visy[j]) ly[j]+=d; else slack[j]-=d; } } int res=0; for(i=1;i<=ny;i++){ if(link[i]>-1) res+=w[link[i]][i]; } return res; } int main() { int i,j; while(scanf("%d",&n)!=EOF){ nx=ny=n; for(i=1;i<=nx;i++) for(j=1;j<=ny;j++) scanf("%d",&w[i][j]); printf("%d\n",KM()); } return 0; }
相关文章推荐
- hdu 4336 Card Collector (概率dp)
- 程序员技术练级攻略
- require和include区别
- 将json对象排序
- 顺序栈
- 撒切尔:白岩松的话都是骗人的
- UITableView的基本使用一
- 搞笑及优秀文字收集
- CocoaPods安装和使用教程
- 树的子结构
- PHP 类的继承 extends 关键字
- iOS Dev (48) initializer 和 convenience constructor
- PowerShell常用命令整理
- 数据库索引运用和优化
- PHP 类与对象
- 自定义T4模板去掉实体对象中的下划线
- Linux下的samba安装
- 软件开发实践的24条军规
- java程序员必知的 8大排序
- 关于malloc和free函数的用法