/****************************************************** 二分图最佳匹配 (kuhn munkras 算法 O(m*m*n)). 邻接矩阵形式 。 返回最佳匹配值,传入二分图大小m,n 邻接矩阵 map ,表示权,m1,m2返回一个最佳匹配,为匹配顶点的match值为-1, 一定注意m<=n,否则循环无法终止,最小权匹配可将全职取相反数。 初始化: for(i=0;i<MAXN;i++) for(j=0;j<MAXN;j++) mat[i][j]=-inf; 对于存在的边:mat[i][j]=val;//注意不能负值 ********************************************************/ #define MAXN 15 int n,m; int m1[MAXN]; int m2[MAXN]; bool isequal(double a,double b) { if(fabs(a-b)<0.00000001) return 1; return 0; } double km_match(int m,int n,double map[][MAXN]) { int s[MAXN],t[MAXN]; double l1[MAXN],l2[MAXN]; int p,q,i,j,k; double res=0; for(i=0;i<m;i++) { l1[i]=-10000000; for(j=0;j<n;j++) l1[i]=map[i][j]>l1[i]?map[i][j]:l1[i]; if(isequal(l1[i],-10000000)) return -1; } for(i=0;i<n;i++) l2[i]=0; memset(m1,-1,sizeof(m1)); memset(m2,-1,sizeof(m2)); for(i=0;i<m;i++) { memset(t,-1,sizeof(t)); p=0;q=0; for(s[0]=i;p<=q&&m1[i]<0;p++) { for(k=s[p],j=0;j<n&&m1[i]<0;j++) { if(isequal(l1[k]+l2[j],map[k][j])&&t[j]<0) { s[++q]=m2[j]; t[j]=k; if(s[q]<0) { for(p=j;p>=0;j=p) { m2[j]=k=t[j]; p=m1[k]; m1[k]=j; } } } } } if(m1[i]<0) { i--; double pp=10000000; for(k=0;k<=q;k++) { for(j=0;j<n;j++) { if(t[j]<0&&l1[s[k]]+l2[j]-map[s[k]][j]<pp) pp=l1[s[k]]+l2[j]-map[s[k]][j]; } } for(j=0;j<n;j++) l2[j]+=t[j]<0?0:pp; for(k=0;k<=q;k++) l1[s[k]]-=pp; } } for(i=0;i<m;i++) res+=map[i][m1[i]]; return res; }
时间: 2024-10-19 20:35:13