[gotoac]二分图最大匹配hungary & 二分图最佳完美匹配KM(邻接表&邻接矩阵) beta1
2012-11-30 16:22
555 查看
struct hungary{ int n,m; //X集和Y集的点数 int match[M]; //匹配 bool vis[M]; //是否在增广路上 vector<int>g[M]; //邻接表 void init(int _n,int _m){ n=_n,m=_m,clr(match,-1,m); for(int i=0;i<n;i++) g[i].clear(); } void insert(int u,int v){g[u].push_back(v);} bool augment(int u){//增广 for(int i=0,v;i<g[u].size();i++){ if(!vis[v=g[u][i]]){ vis[v]=1; if(match[v]==-1 || augment(match[v])){ match[v]=u; return true; } } } return false; } int maxMatch(){ int res=0; for(int i=0;i<n;i++){ clr(vis,0,m); if(augment(i)) res++; } return res; } };
struct KM{//邻接表 typedef int type; struct edge{ int from,to; type w; edge(int u,int v,type _w){from=u,to=v,w=_w;} }; int n,m; // X/Y集的点数 int match[M]; // 匹配 type lx[M],ly[M],d; // X/Y项标,松弛量 bool vx[M],vy[M]; // X/Y集的点是否在已经访问 vector<edge>edg; // 边表 vector<int>g[M]; // 邻接表 void init(int _n,int _m){ n=_n,m=_m; clr(match,-1,m),edg.clear(); for(int i=0;i<n;i++) g[i].clear(); } void insert(int u,int v,type w){ edg.push_back(edge(u,v,w)); g[u].push_back(edg.size()-1); } bool augment(int u){// 增广 vx[u]=1; for(int i=0;i<g[u].size();i++){ edge& e=edg[g[u][i]]; if(vy[e.to]) continue; if(lx[u]+ly[e.to]==e.w){ vy[e.to]=1; if(match[e.to]==-1 || augment(match[e.to])){ match[e.to]=u; return true; } }else getmin(d,lx[u]+ly[e.to]-e.w); } return false; } type maxWeight(){ int i,j; for(i=0;i<m;i++) ly[i]=0; for(i=0;i<n;i++){ lx[i]=-INF; for(j=0;j<g[i].size();j++) getmax(lx[i],edg[g[i][j]].w); } for(i=0;i<n;i++){ for(;;){ clr(vx,0,n),clr(vy,0,m); d=-1; if(augment(i)) break; for(j=0;j<n;j++) if(vx[j]) lx[j]-=d; for(j=0;j<m;j++) if(vy[j]) ly[j]+=d; } } type res=0; for(i=0;i<n;i++) res+=lx[i]; for(i=0;i<m;i++) res+=ly[i]; return res; } };
struct KM{//邻接矩阵 typedef int type; int n,m,match[M]; // X/Y集的点数,匹配 type lx[M],ly[M],w[M][M],d;// X/Y项标,松弛量 bool vx[M],vy[M]; // X/Y集的点是否在已经访问 void init(int _n,int _m){ n=_n,m=_m,clr(match,-1,m); for(int i=0;i<n;i++) for(int j=0;j<m;j++) w[i][j]=-INF; } bool augment(int u){//增广 vx[u]=1; for(int v=0;v<m;v++){ if(vy[v]) continue; if(lx[u]+ly[v]==w[u][v]){ vy[v]=1; if(match[v]==-1 || augment(match[v])){ match[v]=u; return true; } }else getmin(d,lx[u]+ly[v]-w[u][v]); } return false; } type maxWeight(){ int i,j; for(i=0;i<m;i++) ly[i]=0; for(i=0;i<n;i++){ lx[i]=-INF; for(j=0;j<m;j++) getmax(lx[i],w[i][j]); } for(i=0;i<n;i++){ for(;;){ clr(vx,0,n),clr(vy,0,m); d=-1; if(augment(i)) break; for(j=0;j<n;j++) if(vx[j]) lx[j]-=d; for(j=0;j<m;j++) if(vy[j]) ly[j]+=d; } } type res=0; for(i=0;i<n;i++) res+=lx[i]; for(i=0;i<m;i++) res+=ly[i]; return res; } };
相关文章推荐
- [gotoac]网络流SAP(邻接表&邻接矩阵) beta2
- HDU 3729-I'm Telling the Truth-周赛4补题-二分图最大匹配-邻接表
- HDOJ 2063 过山车 ——二分图最大匹配(以邻接矩阵,邻接表为数据结构的匈牙利算法)
- POJ 1469 COURSES(二分图最大匹配) (矩阵和邻接表的模板题)
- hdu 3729 I'm Telling the Truth(二分图最大匹配)
- 利用匈牙利算法&Hopcroft-Karp算法解决二分图中的最大二分匹配问题 例poj 1469 COURSES
- 利用匈牙利算法&Hopcroft-Karp算法解决二分图中的最大二分匹配问题
- 二分图的最大匹配、完美匹配和匈牙利算法(转自Renfei Song's Blog)
- 二分图最大匹配的König定理及其证明
- 【二分图最大匹配】【匈牙利算法】poj1469 COURSES && poj2446 Chessboard
- NYOJ 237 游戏高手的烦恼 && POJ3041-Asteroids ( 二分图的最大匹配 )
- 二分图最大匹配 网络流&匈牙利
- 二分图最大匹配的König定理及其证明(转自matrix67.com)
- 二分图:最大独立集&最大匹配&最小顶点覆盖
- POJ 3189--Steady Cow Assignment【二分图多重匹配 && 最大流求解 && 枚举 && 经典】
- NYOJ239 月老的难题 【二分图最大匹配·匈牙利】
- 二分图最大匹配 & 最大独立集
- 二分图最大权匹配 费用流&KM
- poj 1904 King's Quest tarjan求二分图的所有可选最大匹配边
- 二分图最大匹配 pascal