共有N个管理者和N个雇员,每个雇员会跟随一个管理者。每个雇员会对管理者的喜好程度进行排名,管理者也同样会对雇员进行排名,问如何对管理者和雇员进行配对使总排名的平均值最小。
如果最喜欢,设为0,以此递减。
之后对于(i,j)建边两者相加的和。
求最小权,也就是匹配之后的最小值ans。
平均值就是ans/(2*n)。
之后要求输出所有的匹配情况。
就是dfs,当总值达到ans且所有老板都访问过了,那就输出每个老板对应的员工。之后继续dfs
- #include <stdio.h>
- #include <string.h>
- const int inf=1<<30;
- int w[20][20],n,km1[20],km2[20],d,pre[20],cnt,ans;
- bool visx[20],visy[20];
- void init()
- {
- memset(km2,0,sizeof(km2));
- memset(pre,-1,sizeof(pre));
- for(int i=1; i<=n; i++)
- {
- km1[i]=w[i][1];
- for(int j=2; j<=n; j++)
- {
- if(km1[i]<w[i][j])km1[i]=w[i][j];
- }
- }
- }
- bool dfs(int src)
- {
- visx[src]=true;
- for(int i=1; i<=n; i++)
- {
- if(!visy[i])
- {
- int t=km1[src]+km2[i]-w[src][i];
- if(!t)
- {
- visy[i]=true;
- if(pre[i]==-1||dfs(pre[i]))
- {
- pre[i]=src;
- return true;
- }
- }
- else if(d>t)d=t;
- }
- }
- return false;
- }
- int km()
- {
- for(int i=1; i<=n; i++)
- {
- while(1)
- {
- memset(visx,false,sizeof(visx));
- memset(visy,false,sizeof(visy));
- d=inf;
- if(dfs(i))break;
- for(int j=1; j<=n; j++)
- {
- if(visx[j])km1[j]-=d;
- if(visy[j])km2[j]+=d;
- }
- }
- }
- ans=0;
- for(int i=1; i<=n; i++)
- {
- if(pre[i]!=-1)ans+=w[pre[i]][i];
- }
- return -ans;
- }
- void dfs(int src,int ca)
- {
- if(ca<ans)return;
- if(src>n)
- {
- if(ca!=ans)return;
- printf("Best Pairing %d\n",cnt++);
- for(int i=1; i<=n; i++)
- {
- printf("Supervisor %d with Employee %d\n",i,pre[i]);
- }
- }
- else
- {
- for(int i=1; i<=n; i++)
- {
- if(!visx[i])
- {
- visx[i]=true;
- pre[src]=i;
- dfs(src+1,ca+w[src][i]);
- visx[i]=false;
- }
- }
- }
- }
- int main()
- {
- int t,x,case1=1;
- scanf("%d\n",&t);
- while(t--)
- {
- scanf("%d\n",&n);
- memset(w,0,sizeof(w));
- for(int i=1; i<=n; i++)
- {
- for(int j=1; j<=n; j++)
- {
- scanf("%d",&x);
- w[x][i]-=(j-1);
- }
- }
- for(int i=1; i<=n; i++)
- {
- for(int j=1; j<=n; j++)
- {
- scanf("%d",&x);
- w[i][x]-=(j-1);
- }
- }
- init();
- printf("Data Set %d, Best average difference: %lf\n",case1++,(km()*0.5)/n);
- memset(visx,0,sizeof(visx));
- cnt=1;
- dfs(1,0);
- printf("\n");
- }
- return 0;
- }