Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 2055 | Accepted: 581 |
Description
Input
Output
Sample Input
2 7 1 2 3 4 5 6 7 2 1 3 4 5 6 7 3 1 2 4 5 6 7 4 1 2 3 5 6 7 5 1 2 3 4 6 7 6 1 2 3 4 5 7 7 1 2 3 4 5 6 1 2 3 4 5 6 7 2 1 3 4 5 6 7 3 1 2 4 5 6 7 4 1 2 3 5 6 7 5 1 2 3 4 6 7 6 1 2 3 4 5 7 7 1 2 3 4 5 6 2 1 2 2 1 1 2 1 2
Sample Output
Data Set 1, Best average difference: 0.000000 Best Pairing 1 Supervisor 1 with Employee 1 Supervisor 2 with Employee 2 Supervisor 3 with Employee 3 Supervisor 4 with Employee 4 Supervisor 5 with Employee 5 Supervisor 6 with Employee 6 Supervisor 7 with Employee 7 Data Set 2, Best average difference: 0.250000 Best Pairing 1 Supervisor 1 with Employee 1 Supervisor 2 with Employee 2 题意:老板对员工有一个评价值,评价值越低表示对其好感度越高。员工对老板也有一个评价值,也是评价值越低表示对其好感度越高。求二者最优匹配,使得差异平均值最小。
最小权匹配,然后路径输出(学习于网上)。
权值为正,直接最小权匹配模板代码。
#include<iostream> #include<stdio.h> #include<string.h> using namespace std; #define inf 9999999 #define maxn 100 int lx[maxn],ly[maxn]; int Match[maxn]; int visx[maxn],visy[maxn]; int w[maxn][maxn]; int slack[maxn]; int y[maxn],count; int ans,n,m; bool findPath(int x) { visx[x]=1; for(int y=1; y<=n; y++) { if(visy[y])continue; if(w[x][y]==lx[x]+ly[y]) { visy[y]=1; if(!Match[y]||findPath(Match[y])) { Match[y]=x; return true; } } else slack[y]=min(slack[y],w[x][y]-lx[x]-ly[y]); } return false; } void km() { memset(Match,0,sizeof(Match)); memset(ly,0,sizeof(ly)); for(int i=1; i<=n; i++) { lx[i]=inf; for(int j=1; j<=n; j++) lx[i]=min(lx[i],w[i][j]); } for(int x=1; x<=n; x++) { for(int i=1; i<=n; i++) slack[i]=inf; while(true) { memset(visx,0,sizeof(visx)); memset(visy,0,sizeof(visy)); if(findPath(x))break; int tmp=inf; for(int i=1; i<=n; i++) { if(!visy[i]) { if(tmp>slack[i]) tmp=slack[i]; } } if(tmp==inf)return ; for(int i=1; i<=n; i++) { if(visx[i])lx[i]+=tmp; if(visy[i])ly[i]-=tmp; } } } } void dfs(int t,int sum)//dfs输出匹配 { int i,j; if(sum>ans)return; if(t>n) { if(sum!=ans)return; printf("Best Pairing %d\n",++count); for(j=1;j<=n;j++) printf("Supervisor %d with Employee %d\n",j,y[j]); return ; } for(i=1;i<=n;i++) { if(!visy[i]) { y[t]=i; visy[i]=1; dfs(t+1,sum+w[t][i]); visy[i]=0; } } return; } int main() { int cas,val; cin>>cas; for(int cc=1; cc<=cas; cc++) { cin>>n; for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) { w[i][j]=0; } for(int i=1; i<=n; i++) for(int j=0; j<n; j++) { cin>>val; w[val][i]+=j; } for(int i=1; i<=n; i++) for(int j=0; j<n; j++) { cin>>val; w[i][val]+=j; } km(); ans=0; count=0; for(int i=1; i<=n; i++) if(Match[i]) ans+=w[Match[i]][i]; printf("Data Set %d, Best average difference: %.6f\n",cc,ans/(2.0*n)); memset(visy,0,sizeof(visy)); dfs(1,0); cout<<endl; } return 0; } /* 2 7 1 2 3 4 5 6 7 2 1 3 4 5 6 7 3 1 2 4 5 6 7 4 1 2 3 5 6 7 5 1 2 3 4 6 7 6 1 2 3 4 5 7 7 1 2 3 4 5 6 1 2 3 4 5 6 7 2 1 3 4 5 6 7 3 1 2 4 5 6 7 4 1 2 3 5 6 7 5 1 2 3 4 6 7 6 1 2 3 4 5 7 7 1 2 3 4 5 6 2 1 2 2 1 1 2 1 2 */
权值为负,转为求最大权值后取反模板代码:
#include<iostream> #include<stdio.h> #include<string.h> using namespace std; #define inf 9999999 #define maxn 105 int lx[maxn],ly[maxn]; int Match[maxn]; int visx[maxn],visy[maxn]; int w[maxn][maxn]; int slack[maxn]; int y[maxn]; int link[maxn],count; int ans,n; bool findPath(int x) { visx[x]=1; for(int y=1; y<=n; y++) { if(visy[y])continue; if(w[x][y]==lx[x]+ly[y]) { visy[y]=1; if(!Match[y]||findPath(Match[y])) { Match[y]=x; return true; } } else slack[y]=min(slack[y],lx[x]+ly[y]-w[x][y]); } return false; } void km() { memset(Match,0,sizeof(Match)); memset(ly,0,sizeof(ly)); for(int i=1; i<=n; i++) { lx[i]=-inf; for(int j=1; j<=n; j++) lx[i]=max(lx[i],w[i][j]); } for(int x=1; x<=n; x++) { for(int i=1; i<=n; i++) slack[i]=inf; while(true) { memset(visx,0,sizeof(visx)); memset(visy,0,sizeof(visy)); if(findPath(x))break; int tmp=inf; for(int i=1; i<=n; i++) { if(!visy[i]) { if(tmp>slack[i]) tmp=slack[i]; } } if(tmp==inf)return ; for(int i=1; i<=n; i++) { if(visx[i])lx[i]-=tmp; if(visy[i])ly[i]+=tmp; } } } } void dfs(int dep, int sum) // 深搜构造所有能达到最大值的匹配情况。 { if(sum>ans) return; if(dep>n) { if(sum != ans) return; printf("Best Pairing %d\n", count ++); for(int i = 1; i <= n; i ++) printf("Supervisor %d with Employee %d\n", i, link[i]); } else { for(int i = 1; i <= n; i ++) if(!y[i]) { y[i]=1; link[dep] = i; dfs(dep+1, sum-w[dep][i]); y[i]=0; } } } int main() { int cas,val; cin>>cas; for(int cc=1; cc<=cas; cc++) { cin>>n; for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) { w[i][j]=0; } for(int i=1; i<=n; i++) for(int j=0; j<n; j++) { cin>>val; w[val][i]-=j; } for(int i=1; i<=n; i++) for(int j=0; j<n; j++) { cin>>val; w[i][val]-=j; } km(); ans=0; count=1; for(int i=1; i<=n; i++) if(Match[i]) ans-=w[Match[i]][i]; //cout<<ans<<endl; printf("Data Set %d, Best average difference: %.6f\n",cc,ans/(2.0*n)); memset(y,0,sizeof(y)); dfs(1,0); cout<<endl; } return 0; } /* 2 7 1 2 3 4 5 6 7 2 1 3 4 5 6 7 3 1 2 4 5 6 7 4 1 2 3 5 6 7 5 1 2 3 4 6 7 6 1 2 3 4 5 7 7 1 2 3 4 5 6 1 2 3 4 5 6 7 2 1 3 4 5 6 7 3 1 2 4 5 6 7 4 1 2 3 5 6 7 5 1 2 3 4 6 7 6 1 2 3 4 5 7 7 1 2 3 4 5 6 2 1 2 2 1 1 2 1 2 */