hdu2255
2014-08-07 23:36
288 查看
KM水题。KM是求完备匹配下的最优匹配。直接贴代码:
608K+604MS
若要求最小费用则代码如下:
608K+604MS
#include <stdio.h> #include <stdlib.h> #include <string.h> #define Max 310 #define Inf 1000010 int match[Max][Max]; bool visy[Max]; bool visx[Max]; int pre[Max]; int slack[Max]; int lx[Max]; int ly[Max]; int n; bool find(int x){ visx[x]=true; for(int i=1;i<=n;i++){ if(visy[i]) continue; int t=lx[x]+ly[i]-match[x][i]; if(t==0){ visy[i]=true; if(pre[i]==-1 || find(pre[i])){ pre[i]=x; return true; } } else if(t<slack[i]) slack[i]=t; } return false; } int Km(){ memset(ly,0,sizeof(ly)); memset(pre,-1,sizeof(pre)); int i,j; for(i=1;i<=n;i++) for(j=1,lx[i]=-Inf;j<=n;j++) if(lx[i]<match[i][j]) lx[i]=match[i][j]; for(i=1;i<=n;i++){ for(j=1;j<=n;j++) slack[j]=Inf; while(true){ memset(visx,0,sizeof(visx)); memset(visy,0,sizeof(visy)); if(find(i)) break; int d=Inf; for(j=1;j<=n;j++) if(!visy[j] && slack[j]<d) d=slack[j]; for(j=1;j<=n;j++) if(visx[j]) lx[j]-=d; for(j=1;j<=n;j++) if(visy[j]) ly[j]+=d; else slack[j]-=d; } } int ans=0; for(i=1;i<=n;i++) if(pre[i]!=-1) ans+=match[pre[i]][i]; return ans; } int main(){ while(scanf("%d",&n)!=EOF){ for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&match[i][j]); printf("%d\n",Km()); } return 0; }
若要求最小费用则代码如下:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define Max 310 #define Inf 1000010 int match[Max][Max]; bool visy[Max]; bool visx[Max]; int pre[Max]; int slack[Max]; int lx[Max]; int ly[Max]; int n; bool find(int x){ visx[x]=true; for(int i=1;i<=n;i++){ if(visy[i]) continue; int t=match[x][i]-(lx[x]+ly[i]); if(t==0){ visy[i]=true; if(pre[i]==-1 || find(pre[i])){ pre[i]=x; return true; } } else if(t<slack[i]) slack[i]=t; } return false; } int Km(){ memset(ly,0,sizeof(ly)); memset(pre,-1,sizeof(pre)); int i,j; for(i=1;i<=n;i++) for(j=1,lx[i]=Inf;j<=n;j++) if(lx[i]>match[i][j]) lx[i]=match[i][j]; for(i=1;i<=n;i++){ for(j=1;j<=n;j++) slack[j]=Inf; while(true){ memset(visx,0,sizeof(visx)); memset(visy,0,sizeof(visy)); if(find(i)) break; int d=Inf; for(j=1;j<=n;j++) if(!visy[j] && slack[j]<d) d=slack[j]; for(j=1;j<=n;j++) if(visx[j]) lx[j]+=d; for(j=1;j<=n;j++) if(visy[j]) ly[j]-=d; else slack[j]-=d; } } int ans=0; for(i=1;i<=n;i++) if(pre[i]!=-1) ans+=match[pre[i]][i]; return ans; } int main(){ while(scanf("%d",&n)!=EOF){ for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&match[i][j]); printf("%d\n",Km()); } return 0; }
相关文章推荐
- hdu2255 二分图的最佳匹配 KM算法
- hdu2255二分图最大权匹配
- HDU2255-奔小康赚大钱
- HDU2255--奔小康赚大钱(KM算法)
- HDU2255 奔小康赚大钱【二分图最佳匹配】
- hdu2255 奔小康赚大钱,最大权匹配,KM算法
- hdu2255 奔小康赚大钱
- 【二分图完美匹配】【KM算法】hdu2255 奔小康赚大钱 && hdu1853 Cyclic Tour
- hdu2255奔小康赚大钱 KM算法
- HDU2255(KB10-K 二分图最大权匹配)
- hdu2255 奔小康赚大钱(二分匹配 KM)模板 邻接矩阵
- HDU2255.奔小康赚大钱——最佳匹配
- 【KM算法】HDU2255-奔小康赚大钱
- HDU2255 奔小康赚大钱 —— KM算法(二分图最大权匹配)
- HDU2255(带权二分图的最大匹配)
- HDU2255 奔小康赚大钱【二分图最佳匹配】
- HDU2255 奔小康赚大钱(km模板题)
- KM算法模板(hdu2255)
- 二分图最佳匹配 KM算法 Hdu2255奔小康赚大钱 + Poj 3565 Ants
- hdu2255 KM算法入门 KM算法模板