参考题解

二分图的最优匹配。图很容易建立。再处理相似度的时候。把每个权值扩大100倍。然后再对i==j时 特殊标记。使他们的权值再++1。后面选择的时候就很容易挑出。按原匹配

匹配的个数。 100*(double)(res%100)/n。即可得到第二问。

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <vector>
  6. #include <queue>
  7. using namespace std;
  8.  
  9. const int maxn = ;
  10. const int INF = 0x3f3f3f3f;
  11.  
  12. int n;
  13.  
  14. int V[maxn], H[maxn], P[maxn], A[maxn], B[maxn];
  15.  
  16. // KM algorithm
  17. int W[maxn][maxn], lft[maxn];
  18. int slack[maxn];
  19. int Lx[maxn], Ly[maxn];
  20. bool S[maxn], T[maxn];
  21.  
  22. int inline divide(int a, int b) { int ans = a / b; if(a % b) ans++; return ans; }
  23.  
  24. bool match(int u)
  25. {
  26. S[u] = true;
  27. for(int v = ; v <= n; v++) if(!T[v])
  28. {
  29. int t = Lx[u] + Ly[v] - W[u][v];
  30. if(t == )
  31. {
  32. T[v] = true;
  33. if(!lft[v] || match(lft[v]))
  34. {
  35. lft[v] = u;
  36. return true;
  37. }
  38. }
  39. else slack[v] = min(slack[v], t);
  40. }
  41.  
  42. return false;
  43. }
  44.  
  45. void update()
  46. {
  47. int a = INF;
  48. for(int i = ; i <= n; i++) if(!T[i]) a = min(a, slack[i]);
  49. for(int i = ; i <= n; i++)
  50. {
  51. if(S[i]) Lx[i] -= a;
  52.  
  53. if(T[i]) Ly[i] += a;
  54. else slack[i] -= a;
  55. }
  56. }
  57.  
  58. void KM()
  59. {
  60. memset(Ly, , sizeof(Ly));
  61. memset(lft, , sizeof(lft));
  62. for(int i = ; i <= n; i++) Lx[i] = -INF;
  63. for(int i = ; i <= n; i++)
  64. for(int j = ; j <= n; j++) Lx[i] = max(Lx[i], W[i][j]);
  65.  
  66. for(int i = ; i <= n; i++)
  67. {
  68. memset(slack, 0x3f, sizeof(slack));
  69. for(;;)
  70. {
  71. memset(S, false, sizeof(S));
  72. memset(T, false, sizeof(T));
  73. if(match(i)) break;
  74. update();
  75. }
  76. }
  77. }
  78.  
  79. int main()
  80. {
  81. while(scanf("%d", &n) == && n)
  82. {
  83. for(int i = ; i <= n; i++) scanf("%d", V + i);
  84. for(int i = ; i <= n; i++) scanf("%d", H + i);
  85. for(int i = ; i <= n; i++) scanf("%d", P + i);
  86. for(int i = ; i <= n; i++) scanf("%d", A + i);
  87. for(int i = ; i <= n; i++) scanf("%d", B + i);
  88.  
  89. //build graph
  90. for(int i = ; i <= n; i++)
  91. for(int j = ; j <= n; j++)
  92. {
  93. int score = V[i] * ;
  94. int round1 = divide(P[j], A[i]);
  95. int round2 = divide(H[i], B[j]);
  96. if(round1 > round2) score = -score;
  97. if(i == j) score++;
  98. W[i][j] = score;
  99. }
  100.  
  101. KM();
  102.  
  103. int ans = ;
  104. for(int i = ; i <= n; i++) ans += W[lft[i]][i];
  105.  
  106. if(ans < )
  107. {
  108. puts("Oh, I lose my dear seaco!");
  109. continue;
  110. }
  111.  
  112. printf("%d ", ans / );
  113. printf("%.3f%%\n", 100.0 * (ans % ) / n);
  114. }
  115.  
  116. return ;
  117. }

代码君

HDU 3315 KM My Brute的更多相关文章

  1. HDU 3315 My Brute(费用流)

    职务地址:HDU 3315 这个题的思路全然是自己想出来的,自我感觉挺巧妙的. . .(大牛勿喷.. . )对大胆建图又多了一份信心. 详细思路是构造一个二分图,Si连源点.Xi连汇点,流量都是1,费 ...

  2. My Brute HDU - 3315(KM || 费用流)

    题意: 有S1到Sn这n个勇士要和X1到Xn这n个勇士决斗,初始时,Si的决斗对象是Xi. 如果Si赢了Xi,那么你将获得Vi分,否则你将获得-Vi分. Si和Xi对决时,Si有初始生命Hi,初始攻击 ...

  3. HDU 3315 My Brute(二分图最佳匹配+尽量保持原先匹配)

    http://acm.hdu.edu.cn/showproblem.php?pid=3315 题意: 有S1到Sn这n个勇士要和X1到Xn这n个勇士决斗,初始时,Si的决斗对象是Xi. 如果Si赢了X ...

  4. HDU 2853 && HDU 3315

    http://acm.hdu.edu.cn/showproblem.php?pid=2853 题意:给一个n-m二分图,边权用一个n*m的矩阵表示,给出初始匹配,求二分图完美匹配相比初始匹配改变了几条 ...

  5. HDU 2853 (KM最大匹配)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2853 题目大意:二分图匹配费用流.①最大匹配②最小原配变动 解题思路: 如果去掉第二个要求,那么就是裸 ...

  6. 奔小康赚大钱 hdu 2255( KM )

    http://acm.split.hdu.edu.cn/showproblem.php?pid=2255 带权匹配问题: #include <stdio.h> #include <a ...

  7. HDU 2255 & KM模板

    题意: 一张完备二分图求最优完备匹配. SOL: 这题就不讲什么sol了...毕竟是裸的KM,不会的话可以看老人家的大白鼠,一些问题看代码注释.讲讲经历(悲惨的经历) 刚打完,自信地交上去发现MLE. ...

  8. hdu 3488(KM算法||最小费用最大流)

    Tour Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submis ...

  9. hdu 4862 KM算法 最小K路径覆盖的模型

    http://acm.hdu.edu.cn/showproblem.php?pid=4862 选t<=k次,t条路要经过全部的点一次而且只一次. 建图是问题: 我自己最初就把n*m 个点分别放入 ...

随机推荐

  1. bug {was not declared in this scope}

    使用自己定义的结构体作为返回值的时候,出现了 ...was not declared in this scope 检查了各种头文件,把缓存也都删掉了还是不行. 结果,发现,应该这样用vector< ...

  2. 以后要进行数据收集,打开邮箱就行了 | formtalk入驻Office 应用商店

    『数据收集』,作为一项工作,存在感高的忽视不了——不管你在企业里是什么角色(大部分),Ta似乎都在你的工作范围内. 你是人事:收集招聘数据.员工信息: 你是采购:收集供应商信息.商品数据: 你是市场: ...

  3. HDU 3681 Prison Break 越狱(状压DP,变形)

    题意: 给一个n*m的矩阵,每个格子中有一个大写字母,一个机器人从‘F’出发,拾取所有的开关‘Y’时便能够越狱,但是每走一格需要花费1点能量,部分格子为充电站‘G’,每个电站只能充1次电.而且部分格子 ...

  4. uva 10328 - Coin Toss 投硬币(dp递推,大数)

    题意:抛出n次硬币(有顺序),求至少k个以上的连续正面的情况的种数. 思路:转换成求抛n个硬币,至多k-1个连续的情况种数,用所有可能出现的情况种数减去至多k-1个的情况,就得到答案了.此题涉及大数加 ...

  5. BZOJ 2539: [Ctsc2000]丘比特的烦恼

    Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 695  Solved: 260[Submit][Status][Discuss] Description ...

  6. 使用nodejs消费SAP Cloud for Customer上的Web service

    Jerry在公众号文章C4C和微信集成系列教程里曾经使用nodejs去消费C4C提供的标准webservice. 看一个具体例子:C4C里Individual Customers可以维护Social ...

  7. cesium模型加载-加载fbx格式模型

    整体思路: fbx格式→dae格式→gltf格式→cesium加载gltf格式模型 具体方法: 1. fbx格式→dae格式 工具:3dsMax, 3dsMax插件:OpenCOLLADA, 下载地址 ...

  8. UVA 10570 Meeting with Aliens 外星人聚会

    题意:给你一个排列,每次可以交换两个整数(不一定要相邻),求最少交换次数把排列变成一个1~n的环形排列.(正反都算) 其实就是找环了,对于一个链状序列,最小交换次数等于不在对应位置的数字个数减去环的个 ...

  9. Ajax获取服务器响应头部信息

    $.ajax({ type: 'HEAD', // 获取头信息,type=HEAD即可 url : window.location.href, complete: function( xhr,data ...

  10. JavaScript 获取对象中第一个属性

    使用 Object.keys(object) 可以取出属性名为数组,但会打乱顺序 严格意义上对象中是只有映射关系而没有顺序的,但是在存储结构里是有顺序的,如果想获取存储结构里的第一个属性可以使用for ...