博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
最大权二分匹配
阅读量:5075 次
发布时间:2019-06-12

本文共 2019 字,大约阅读时间需要 6 分钟。

图论里有一个非常经典的算法,那就是二分匹配,只是仅仅是简单的匹配有时并不能解决我们的问题,比方匹配带权的情况。引申的一个非常重要的问题就是分配问题,比方给n个人分派m个任务,每一个人都有不同的成本,怎样分配能使得成本最小就是这种问题,这种问题我们统称为二分图的最大权匹配问题.

解决这类问题的最好的方法应该就是KM 算法。详细细节能够自己百度!

以下是我的代码,我主要还是用了类来写,认为这样比較好理解!

#include
#include
#include
using namespace std;#define INF 99999999class graph{ struct vertex { bool vist; //是否被訪问过 int link; //顶标 int ver; //匹配边 vector
edge; //相关边 vertex(bool f=0,int v=0,int l=-INF):vist(f),ver(v),link(l){} }; int n,m; vector
V; vector
U; vector
slack; public: graph(int x,int y):n(x),m(y) { vertex tmp; int i=0; for(;i<=n;i++) V.push_back(tmp), V[i].edge.push_back(0); for(i=0;i<=m;i++) U.push_back(tmp), slack.push_back(INF); } void merge(int i,int w) { V[i].edge.push_back(w); V[i].link=V[i].link>w?V[i].link:w; } bool DFS(int x) { V[x].vist=1; for(int y=1;y<=m;y++) { if(U[y].vist) continue; int tmp=V[x].link+U[y].link-V[x].edge[y]; if(tmp==0) { U[y].vist=1; if(U[y].ver==0||DFS(U[y].ver)) { U[y].ver=x; V[x].ver=y; return 1; } } else if(slack[y]>tmp) slack[y]=tmp; } return 0; } int KM() { for(int x=1;x<=n;x++) { for(int i=1;i<=m;i++) slack[i]=INF; while(1) { for(int i=1;i<=n;i++) V[i].vist=0; for(int i=1;i<=m;i++) U[i].vist=0; if(DFS(x)) break; int d=INF ; for(int i=1;i<=m;i++) if(!U[i].vist&&d>slack[i]) d=slack[i]; for(int j=1;j<=n;j++) if(V[j].vist) V[j].link-=d; for(int k=1;k<=m;k++) if(U[k].vist) U[k].link+=d; else slack[k]-=d; } } int MAX=0; for(int i=1;i<=m;i++) { if(V[i].ver>0) MAX+=V[U[i].ver].edge[i]; } return MAX; } };int main(){//freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout); int n,m; while(cin>>n>>m) { graph G(n,n); int w; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&w), G.merge(i,-w); int max=-G.KM(); cout<
<
这个算法的效率是O(n^3)的,这应该是眼下最好的算法了吧。

转载于:https://www.cnblogs.com/yfceshi/p/7258295.html

你可能感兴趣的文章
HDU 5510 Bazinga KMP
查看>>
[13年迁移]Firefox下margin-top问题
查看>>
Zookeeper常用命令 (转)
查看>>
Java程序IP v6与IP v4的设置
查看>>
RUP(Rational Unified Process),统一软件开发过程
查看>>
数据库链路创建方法
查看>>
Enterprise Library - Data Access Application Block 6.0.1304
查看>>
重构代码 —— 函数即变量(Replace temp with Query)
查看>>
Bootstrap栅格学习
查看>>
程序员的数学
查看>>
聚合与组合
查看>>
jQuery如何获得select选中的值?input单选radio选中的值
查看>>
设计模式 之 享元模式
查看>>
如何理解汉诺塔
查看>>
洛谷 P2089 烤鸡【DFS递归/10重枚举】
查看>>
15 FFT及其框图实现
查看>>
Linux基本操作
查看>>
osg ifc ifccolumn
查看>>
C++ STL partial_sort
查看>>
3.0.35 platform 设备资源和数据
查看>>