完备匹配下的最大权匹配-KM算法的一般模板
2013-06-06 18:11
411 查看
#include <iostream> #include<stdio.h> #include<cstring> #include<climits> #include<algorithm> using namespace std; const int maxn=305; int g[maxn][maxn],lx[maxn],ly[maxn]; int match[maxn]; bool visx[maxn],visy[maxn]; int slack[maxn]; int n; bool DFS(int cur)//匈牙利深度搜索算法 { visx[cur]=true; for(int y=1;y<=n;y++) { if(visy[y]) continue; int t=lx[cur]+ly[y]-g[cur][y]; if(t==0) { visy[y]=true; if(match[y]==-1||DFS(match[y])) { match[y]=cur; return true; } } else slack[y] = min(slack[y],t); //不在相等子图 } return false; } int KM_Maxmatch() { memset(match,-1,sizeof(match)); //初始化顶标 memset(ly,0,sizeof(ly));//ly[i]为0 for(int i=1;i<=n;i++) { lx[i]=-INT_MAX; for(int j=1;j<=n;j++)//lx[i]为权值最大的边 { if(g[i][j]>lx[i]) lx[i]=g[i][j]; } } for(int k=1;k<=n;k++) //对n个点匹配 { for(int m=1;m<=n;m++) slack[m]=INT_MAX; while(true) { memset(visx,false,sizeof(visx)); memset(visy,false,sizeof(visy)); if(DFS(k)) break; //匹配成功 int d=INT_MAX;//匹配失败,找最小值 for(int i=1;i<=n;i++)//x在交错树中 { if(!visy[i]&&d>slack[i]) d=slack[i]; } for(int i=1;i<=n;i++)//y在交错树外 { if(visx[i]) lx[i]-=d; } for(int i=1;i<=n;i++)//更新顶标 { if(visy[i]) visy[i]+=d; else slack[i]-=d; } } } int result=0; //权值相加 for(int i=1;i<=n;i++) { if(match[i]>-1) result+=g[match[i]][i]; } return result; } int main() { int i,j; while(scanf("%d",&n)!=EOF) { for(i=1;i<=n;i++) for(j=1;j<=n;j++) scanf("%d",&g[i][j]); int ans=KM_Maxmatch(); printf("%d\n",ans); } return 0; }
相关文章推荐
- uoj#79. 一般图最大匹配【带花树模板】
- hdu 2255 二分图最大权匹配 km算法模板
- 【UOJ #79】一般图最大匹配 带花树模板
- 一般图最大匹配——带花树模板
- hdu 4687 带花树求一般图最大匹配(模板)
- KM算法模板(二分图的最大权匹配)
- 二分图最大权匹配--KM算法模板
- [模板]带花树算法(一般图最大匹配)
- UOJ 一般图的最大匹配(带花树算法模板)
- KM算法详解+模板(二分图最大权值匹配)
- 一般图最大匹配 带花树算法 模板
- KM算法(二分图完备匹配下的最大权匹配)
- KM算法(完备匹配下的最大权匹配)
- 【二分图最大权匹配】【KM算法模板】
- 一般图最大匹配-带花树-带注释模板
- UOJ-79 一般图的最大匹配(带花树模板求解)
- 【BZOJ4405】挑战NPC 带花树模板 一般图最大匹配
- KM算法 求二分图最大权值的完美匹配 【模板 记录】
- 【模板】KM算法模板(带注释)——二分图带权最大匹配
- 最大权二分匹配—KM算法入门 && 模板