POJ2400 KM最大匹配

来源:互联网 发布:js滑动幻灯片轮播代码 编辑:程序博客网 时间:2024/05/29 09:32
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<iostream>#include<algorithm>#define For(i,j,k) for (i=j;i<=k;i++)using namespace std;const int dmax=1010,INF=100000000;int a[dmax][dmax],lx[dmax],ly[dmax],slack[dmax],d[dmax],ans,n,T,t1,t;bool px[dmax],py[dmax];void dfs(int x,int sum){int i;if (sum>ans) return;if (x>n){if (ans!=sum) return;printf("Best Pairing %d\n",++t);For(i,1,n)printf("Supervisor %d with Employee %d\n",i,d[i]);return;}For(i,1,n)if (!py[i]){d[x]=i,py[i]=1;dfs(x+1,sum-a[x][i]);py[i]=0;}}bool dfs(int x){int i,tmp;px[x]=1;For(i,1,n){if (py[i]) continue;tmp=lx[x]+ly[i]-a[x][i];if (tmp==0){py[i]=1;if (!d[i] || dfs(d[i])){d[i]=x;return 1;}}else if (tmp<slack[i])slack[i]=tmp;}return 0;}int main(){int i,j,k,m;scanf("%d",&T);For(t1,1,T){ans=0;memset(d,0,sizeof(d));memset(a,0,sizeof(a));scanf("%d",&n);For(i,1,n)For(j,1,n){scanf("%d",&k);a[k][i]-=j-1;}For(i,1,n)For(j,1,n){scanf("%d",&k);a[i][k]-=j-1;}For(i,1,n){lx[i]=-INF;For(j,1,n)if (a[i][j]>lx[i])lx[i]=a[i][j];}memset(ly,0,sizeof(ly));For(i,1,n){For(j,1,n) slack[j]=INF;while (1){memset(px,0,sizeof(px));memset(py,0,sizeof(py));if (dfs(i)) break;int min=INF;For(j,1,n)if (!py[j] && slack[j]<min)min=slack[j];For(j,1,n)if (px[j])lx[j]-=min;For(j,1,n)if (py[j])ly[j]+=min;else slack[j]-=min;}}For(i,1,n) ans-=a[d[i]][i];printf("Data Set %d, Best average difference: %.6f\n",t1,0.5*ans/n);memset(py,0,sizeof(py));memset(d,0,sizeof(d));t=0;dfs(1,0);puts("");}return 0;}

0 0
原创粉丝点击