首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐
2025年6月1日 星期日 3:46am

poj2400 - Supervisor, Supervisee

  • 24-03-05 07:01
  • 3357
  • 6260
blog.csdn.net

                            想看更多的解题报告:http://iyenn.com/rec/1824570.html
                              转载请注明出处:
http://blog.csdn.net/wangjian8006

题目大意:
有n个老板和n个员工,他们对彼此有一个排名,现在要求选出最好的对应关系使他们平均分值最少

有n个老板和n个员工,首先给出有多少组测试数据,然后给出n
接下来n行,每行有n个数,第i行代表第i个老板对所有员工的喜好排名,排在第一个员工的标号的权值为0,第二个为-1,依次递减
再有n行,每行n个数,代表员工对老板的排名,排在第一个老板的标号的权值为0,第二个为-1,依次递减
这里权值为给对方所评的分数

这里要注意的是,题目的那个矩阵给反了,有可能是题目描述有问题,看discuss才知道的,否则会一直WA
将那个矩阵反过来输入试试就A了,我是将行看成老板,列看成员工的

找出最少平均分值之后,还要输出哪个老板和哪个员工匹配。如果有多个匹配,按字典序输出


解题思路:最少平均分值,用KM找出最佳匹配,使得权值和最小即可,当然他们的权值全为负数,所以当输出的时候要算出相反数

最少平均分值是等于最佳匹配的权值和除上一个总的点数2*n
找出了最少平均分值,最后那个匹配输出直接全排列找匹配,如果他们的权值和等于最佳匹配的权值和,就输出这种情况,直到全排列完即可。

  1. /*
  2. Memory 196K
  3. Time 79MS
  4. */
  5. #include
  6. using namespace std;
  7. #define INF INT_MAX
  8. #define MAXV 16
  9. #define min(a,b) (a>b?b:a)
  10. #define max(a,b) (a>b?a:b)
  11. int n,sum,cost;
  12. int ly[MAXV],lx[MAXV],link[MAXV],tx[MAXV],ty[MAXV];
  13. int map[MAXV][MAXV],mark[MAXV];
  14. void init(){ //KM初始化
  15. int i,j;
  16. memset(link,-1,sizeof(link));
  17. cost=0;
  18. for(i=1;i<=n;i++) {ly[i]=0;lx[i]=map[i][1];}
  19. for(i=1;i<=n;i++){
  20. for(j=2;j<=n;j++)
  21. lx[i]=max(lx[i],map[i][j]);
  22. }
  23. }
  24. int hungary(int x){ //匈牙利找出完美匹配
  25. int i;
  26. tx[x]=1;
  27. for(i=1;i<=n;i++){
  28. if(!ty[i] && map[x][i]==lx[x]+ly[i]){
  29. ty[i]=1;
  30. if(link[i]==-1 || hungary(link[i])) {
  31. link[i]=x;
  32. return 1;
  33. }
  34. }
  35. }
  36. return false;
  37. }
  38. int km(){
  39. int i,tmp,j,k;
  40. init();
  41. for(i=1;i<=n;i++){
  42. while(1){
  43. memset(tx,0,sizeof(tx));
  44. memset(ty,0,sizeof(ty));
  45. if(hungary(i)) break;
  46. tmp=INF;
  47. for(j=1;j<=n;j++){
  48. if(tx[j]){
  49. for(k=1;k<=n;k++){
  50. if(!ty[k]){
  51. tmp=min(tmp,lx[j]+ly[k]-map[j][k]);
  52. }
  53. }
  54. }
  55. }
  56. for(j=1;j<=n;j++) {
  57. if(tx[j]) lx[j]-=tmp;
  58. if(ty[j]) ly[j]+=tmp;
  59. }
  60. }
  61. }
  62. for(i=1;i<=n;i++)
  63. if(link[i]!=-1) cost+=map[link[i]][i];
  64. return -cost; //因为求出的最佳匹配的权值是负的,所以输出相反值
  65. }
  66. void dfs(int cap,int x){ //全排列搜索找出所有答案
  67. if(xreturn ;
  68. if(cap>n){
  69. if(x!=cost) return ;
  70. printf("Best Pairing %d\n",++sum);
  71. for(int i=1;i<=n;i++)
  72. printf("Supervisor %d with Employee %d\n",i,link[i]);
  73. }else{
  74. for(int i=1;i<=n;i++){
  75. if(!mark[i]){
  76. mark[i]=1;
  77. link[cap]=i;
  78. dfs(cap+1,x+map[cap][i]);
  79. mark[i]=0;
  80. }
  81. }
  82. }
  83. }
  84. int main(){
  85. int t,i,j,cnt,x;
  86. scanf("%d",&t);
  87. for(cnt=1;cnt<=t;cnt++){
  88. memset(map,0,sizeof(map));
  89. scanf("%d",&n);
  90. for(i=1;i<=n;i++){
  91. for(j=0;j
  92. scanf("%d",&x);
  93. map[x][i]-=j;
  94. }
  95. }
  96. for(i=1;i<=n;i++){
  97. for(j=0;j
  98. scanf("%d",&x);
  99. map[i][x]-=j;
  100. }
  101. }
  102. //平均差异是最佳匹配权值km()和除上总的点数2*n
  103. printf("Data Set %d, Best average difference: %.6lf\n",cnt,0.5*km()/n);
  104. sum=0;
  105. memset(mark,0,sizeof(mark));
  106. dfs(1,0);
  107. printf("\n");
  108. }
  109. return 0;
  110. }


 

注:本文转载自blog.csdn.net的wangjian8006的文章"http://blog.csdn.net/wangjian8006/article/details/7950005"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top