题目链接

看到这题我想到了以前做过的一题,名字记不清了,反正里面有“矩阵”二字,然后是道二分图匹配的题。

经典的行列连边网络流。

第\(i\)行和第\(j\)列连边,费用为\(b[i][j]-a[i][j]\times mid\),源点连行,列连汇点,跑最小费用最大流得到的最小费用取负,这个值就是最大的\(\sum a[i][j]-b[i][j]\times mid\),于是愉快的二分。

其实费用取反跑最小费用最大流再取反就是最大费用最大流。为什么不直接写最大费用最大流?我写WA了?反正就是错了。血的教训

  1. #include <cstdio>
  2. #include <queue>
  3. #include <cstring>
  4. #define INF 2147483647
  5. using namespace std;
  6. const int MAXN = 500;
  7. const int MAXM = 200010;
  8. const double eps = 1e-8;
  9. queue <int> q;
  10. int s, t, now, n;
  11. struct Edge{
  12. int from, next, to, rest;
  13. double cost;
  14. }e[MAXM];
  15. int head[MAXN], num = 1, vis[MAXN], Flow[MAXN], pre[MAXN], a[110][110], b[110][110], o;
  16. double l, r, mid, dis[MAXN];
  17. inline void Add(int from, int to, int flow, double cost){
  18. e[++num] = (Edge){ from, head[from], to, flow, cost }; head[from] = num;
  19. e[++num] = (Edge){ to, head[to], from, 0, -cost }; head[to] = num;
  20. }
  21. int RoadsExist(){
  22. q.push(s);
  23. for(int i = 1; i <= o; ++i)
  24. dis[i] = 1e10, pre[i] = 0;
  25. dis[s] = 0; Flow[s] = INF;
  26. while(!q.empty()){
  27. now = q.front(); q.pop(); vis[now] = 0;
  28. for(int i = head[now]; i; i = e[i].next)
  29. if(e[i].rest && dis[e[i].to] > dis[now] + e[i].cost){
  30. dis[e[i].to] = dis[now] + e[i].cost;
  31. pre[e[i].to] = i;
  32. Flow[e[i].to] = min(Flow[now], e[i].rest);
  33. if(!vis[e[i].to]){
  34. vis[e[i].to] = 1;
  35. q.push(e[i].to);
  36. }
  37. }
  38. }
  39. return pre[t];
  40. }
  41. double ek(){
  42. double maxcost = 0;
  43. while(RoadsExist()){
  44. maxcost += (double)Flow[t] * dis[t];
  45. for(int i = t; i != s; i = e[pre[i]].from){
  46. e[pre[i]].rest -= Flow[t];
  47. e[pre[i] ^ 1].rest += Flow[t];
  48. }
  49. }
  50. return -maxcost;
  51. }
  52. int main(){
  53. scanf("%d", &n); o = (n << 1) + 2; s = o - 1; t = o;
  54. for(int i = 1; i <= n; ++i)
  55. for(int j = 1; j <= n; ++j){
  56. scanf("%d", &a[i][j]);
  57. r += a[i][j];
  58. }
  59. for(int i = 1; i <= n; ++i)
  60. for(int j = 1; j <= n; ++j)
  61. scanf("%d", &b[i][j]);
  62. while(r - l > eps){
  63. num = 1; mid = (l + r) / 2.0;
  64. for(int i = 1; i <= o; ++i) head[i] = 0;
  65. for(int i = 1; i <= n; ++i){
  66. Add(s, i, 1, 0), Add(i + n, t, 1, 0);
  67. for(int j = 1; j <= n; ++j)
  68. Add(i, j + n, 1, -(double)a[i][j] + (double)b[i][j] * mid);
  69. }
  70. if(ek() <= 0) r = mid;
  71. else l = mid;
  72. }
  73. printf("%.6lf\n", l);
  74. return 0;
  75. }

【洛谷 P3705】 [SDOI2017]新生舞会(费用流,01分数规划)的更多相关文章

  1. BZOJ 4819 [Sdoi2017]新生舞会 ——费用流 01分数规划

    比值最大 分数规划 二分答案之后用费用流进行验证. 据说标称强行乘以1e7换成了整数的二分. 不过貌似实数二分也可以过. #include <map> #include <cmath ...

  2. 洛谷 P3705 [SDOI2017]新生舞会 解题报告

    P3705 [SDOI2017]新生舞会 题目描述 学校组织了一次新生舞会,\(Cathy\)作为经验丰富的老学姐,负责为同学们安排舞伴. 有\(n\)个男生和\(n\)个女生参加舞会买一个男生和一个 ...

  3. 洛谷3705 [SDOI2017] 新生舞会 【01分数规划】【KM算法】

    题目分析: 裸题.怀疑$ O(n^4log{n}) $跑不过,考虑Edmonds-Karp优化. 代码: #include<bits/stdc++.h> using namespace s ...

  4. 洛谷P2868 [USACO07DEC]观光奶牛Sightseeing Cows(01分数规划)

    题意 题目链接 Sol 复习一下01分数规划 设\(a_i\)为点权,\(b_i\)为边权,我们要最大化\(\sum \frac{a_i}{b_i}\).可以二分一个答案\(k\),我们需要检查\(\ ...

  5. P3705 [SDOI2017]新生舞会 01分数规划+费用流

    $ \color{#0066ff}{ 题目描述 }$ 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴. 有\(n\)个男生和\(n\)个女生参加舞会买一个男生和一个女生一 ...

  6. BZOJ 4819 Luogu P3705 [SDOI2017]新生舞会 (最大费用最大流、二分、分数规划)

    现在怎么做的题都这么水了.. 题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=4819 (luogu) https://ww ...

  7. 【BZOJ4819】【SDOI2017】新生舞会 [费用流][分数规划]

    新生舞会 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 学校组织了一次新生舞会,Cathy ...

  8. 洛谷 1004 dp或最大费用流

    思路: dp方法: 设dp[i][j][k][l]为两条没有交叉的路径分别走到(i,j)和(k,l)处最大价值. 则转移方程为 dp[i][j][k][l]=max(dp[i-1][j][k-1][l ...

  9. 洛谷P4003 无限之环(费用流)

    传送门 神仙题啊……不看题解我可能一年都不一定做得出来……FlashHu大佬太强啦 到底是得有怎样的脑回路才能一眼看去就是费用流啊…… 建好图之后套个板子就好了,那么我们着重来讨论一下怎么建图 首先, ...

  10. 洛谷P4012 深海机器人问题(费用流)

    题目描述 深海资源考察探险队的潜艇将到达深海的海底进行科学考察. 潜艇内有多个深海机器人.潜艇到达深海海底后,深海机器人将离开潜艇向预定目标移动. 深海机器人在移动中还必须沿途采集海底生物标本.沿途生 ...

随机推荐

  1. HTTPD解析介绍

    配置文件全局介绍 (1)主配置文件:/etc/httpd/conf/httpd.conf 全局配置:Section 1: Global Environment 第33行 中心主机配置: Section ...

  2. Objective - C 之协议

    一.创建方法: 二.实现过程: 1.遵循协议: @protocol NurseWorkingProtocol <NSObject>   //<> 表示遵守协议,创建时就有(Nu ...

  3. 双主双写、只备份某些表且要在建表ID自增

    先展示下最终实现的配置 主1的配置(重要的,其他略) log-bin = mysql-bin #必须要有binlog auto_increment_offset = 1 #自增ID的初始值 auto_ ...

  4. 第192天:js---Date对象属性和方法总结

    Date对象构造函数重载方法 一.第一种重载方法---基本 当前时间 //构造函数 - 第一种重载方法:基本 当前时间 console.log('构造函数 - 第一种重载方法:基本 当前时间') da ...

  5. SPOJ3899——Finding Fractions

    SPOJ上的每个题目都做得我泪牛满面. 这个题目也是的.题目意思是给你两个分数a/b和c/d,要你求出一个分数p/q,使得a/b<p/q<c/d,且p最小. 看完题目后半天都没有任何思路哦 ...

  6. java实现PV操作

    package com.jayfulmath.designpattern.command; import java.util.concurrent.Semaphore; /* P(S): ①将信号量S ...

  7. Appium自动化测试框架

    1.在utils包中创建一个AppiumUtil类,这个类是对appium api进行封装的. 代码如下: package utils; import java.net.MalformedURLExc ...

  8. "流量监管"和"流量整形"的区别

    "流量监管" (Traffic Policing) 就是对流量进行控制,通过监督进入交换机端口的流量速率,对超出部分的流量进行"惩罚" (采用监管方式时是直接丢 ...

  9. Redis Scan迭代器遍历操作原理(二)

    续上一篇文章 Redis Scan迭代器遍历操作原理(一)–基础 ,这里着重讲一下dictScan函数的原理,其实也就是redis SCAN操作最有价值(也是最难懂的部分). 关于这个算法的源头,来自 ...

  10. Codeforces 582C. Superior Periodic Subarrays(数学+计数)

    首先可以把 i mod n=j mod n的看成是同一类,i mod s=j mod s的也看成是同一类,也就是i mod gcd(s,n)的是同一类,很好理解,但是不会数学证明...大概可以想成数轴 ...