题目传送门

https://lydsy.com/JudgeOnline/problem.php?id=4819

题解

首先上面说,

\[C = \frac{\sum\limits_{i=1}^n a'_i}{\sum\limits_{i=1}^n b'_i}
\]

要 \(C\) 最大。这是一种非常常见的分数规划模型,于是二分后转化成

\[\sum\limits_{i=1}^n a'_i - k \cdot b'_i \geq 0
\]

于是问题转化为求出权值和最大的方案满足每个人只选择一次。

可以是一个二分图匹配的模型,所以可以转化为最大费用最大流完成。


时间复杂度很玄学,不知道为什么能过。

调了半年的最小费用最大流突然想起来应该维护最大费用最大流。

#include<bits/stdc++.h>

#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;} typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii; template<typename I> inline void read(I &x) {
int f = 0, c;
while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
x = c & 15;
while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
f ? x = -x : 0;
} const int NN = 100 + 7;
const int N = 100 * 100 + 7;
const int M = 100 * 100 + 200 + 7;
const int INF = 0x3f3f3f3f; int n, nod, S, T, hd, tl;
int a[NN][NN], b[NN][NN], id[NN][NN], q[N], inq[N], cur[N], vis[N];
double dis[N]; struct Edge { int to, ne, f; double w; } g[M << 1]; int head[N], tot = 1;
inline void addedge(int x, int y, int z, double w) { g[++tot].to = y, g[tot].f = z, g[tot].w = w, g[tot].ne = head[x], head[x] = tot; }
inline void adde(int x, int y, int f, double w) { addedge(x, y, f, w), addedge(y, x, 0, -w); } inline void qpush(int x) { ++tl; tl == N ? tl = 1 : 0; q[tl] = x; }
inline int qhead() { ++hd; hd == N ? hd = 1 : 0; return q[hd]; }
inline bool spfa() {
for (int i = 1; i <= nod; ++i) dis[i] = -1e9, vis[i] = 0, cur[i] = head[i];
q[hd = 0, tl = 1] = S, inq[S] = 0, dis[S] = 0;
while (hd != tl) {
int x = qhead();
inq[x] = 0;
for fec(i, x, y) if (g[i].f && smax(dis[y], dis[x] + g[i].w) && !inq[y]) qpush(y), inq[y] = 1;
}
return dis[T] > -1e9;
}
inline int dfs(int x, int a, double &mc) {
if (x == T || !a) return mc += dis[x] * a, a;
int f, flow = 0;
vis[x] = 1;
for (int &i = cur[x]; i; i = g[i].ne) {
int y = g[i].to
if (vis[y] || (dis[y] != dis[x] + g[i].w)) continue;
if (!(f = dfs(y, std::min(g[i].f, a), mc))) continue;
g[i].f -= f, g[i ^ 1].f += f;
flow += f, a -= f;
if (!a) return flow;
}
dis[x] = INF;
return flow;
}
inline double mcmf() {
double ans = 0, tmp = 0;
while (spfa()) tmp = 0, dfs(S, INF, tmp), ans += tmp;
return ans;
} inline bool check(double mid) {
memset(head, 0, sizeof(int) * (nod + 1)), tot = 1;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j) adde(i, j + n, 1, a[i][j] - mid * b[i][j]);
for (int i = 1; i <= n; ++i) adde(S, i, 1, 0), adde(i + n, T, 1, 0);
return mcmf() >= 0;
} inline void work() {
S = ++nod, T = ++nod;
double l = 0, r = 1e4 + 7;
while (r - l >= 1e-7) {
double mid = (l + r) / 2;
if (check(mid)) l = mid;
else r = mid;
}
printf("%.6lf\n", l);
} inline void init() {
read(n);
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j) read(a[i][j]), id[i][j] = ++nod;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j) read(b[i][j]);
} int main() {
#ifdef hzhkk
freopen("hkk.in", "r", stdin);
#endif
init();
work();
fclose(stdin), fclose(stdout);
return 0;
}

bzoj4819 [Sdoi2017]新生舞会 分数规划+最大费用最大流的更多相关文章

  1. [BZOJ4819][SDOI2017]新生舞会(分数规划+费用流,KM)

    4819: [Sdoi2017]新生舞会 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1097  Solved: 566[Submit][Statu ...

  2. 【bzoj4819】[Sdoi2017]新生舞会 分数规划+费用流

    题目描述 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴.有n个男生和n个女生参加舞会买一个男生和一个女生一起跳舞,互为舞伴.Cathy收集了这些同学之间的关系,比如两个 ...

  3. 4819: [Sdoi2017]新生舞会 分数规划

    题目 https://www.lydsy.com/JudgeOnline/problem.php?id=4819 思路 分数规划的模板题?(好菜呀) 假如n=3吧(懒得写很长的式子) \(c=\fra ...

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

    #include <algorithm> #include <iterator> #include <iostream> #include <cstring& ...

  5. bzoj 4819: [Sdoi2017]新生舞会【二分+最小费用最大流】

    如果\( b[i]==0 \)那么就是裸的费用流/KM,当然KM快一些但是为什么不写KM呢因为我不会打板子了 考虑二分答案,那么问题变成了判定问题. \[ ans=\frac {a_1+a_2+... ...

  6. BZOJ4819 [Sdoi2017]新生舞会 【01分数规划 + 费用流】

    题目 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴.有n个男生和n个女生参加舞会 买一个男生和一个女生一起跳舞,互为舞伴.Cathy收集了这些同学之间的关系,比如两个人 ...

  7. BZOJ4819: [Sdoi2017]新生舞会(01分数规划)

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1029  Solved: 528[Submit][Status][Discuss] Descripti ...

  8. bzoj4819 [Sdoi2017]新生舞会

    Description 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴.有n个男生和n个女生参加舞会买一个男生和一个女生一起跳舞,互为舞伴.Cathy收集了这些同学之间的 ...

  9. 【BZOJ4819】[Sdoi2017]新生舞会 01分数规划+费用流

    [BZOJ4819][Sdoi2017]新生舞会 Description 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴.有n个男生和n个女生参加舞会 买一个男生和一个女 ...

随机推荐

  1. awk命令1

    [root@a ~]# awk 'END{print NR}' c.txt       #没错,这就是文件的行数,当然,这种统计方法不是linux下最快的,但也是一种思路3[root@a ~]# wc ...

  2. OpenCV学习笔记(1)

    一.读入图像 使用cv2.imread()读入图像,图像应该在此程序的工作路径,第二个参数是告诉函数应该如何读取这幅图片 cv2.IMREAD_COLOR:读入一副彩色图像.图像的透明度会被忽略,这是 ...

  3. Stream之filter、distinct、skip、map、flatMap、match、find、reduce

    一.Stream之filter.distinct.skip: package com.cy.java8; import java.util.Arrays; import java.util.List; ...

  4. JS中设置cookie,读取cookie,删除cookie

    在开发时,碰到一个需求,需要保存一个表的信息(非隐私),希望下次打开还存在.于是想到用cookie,一番折腾完成.示例数据都是假的,打马赛克是怕泄密. 这个表取名为Data,为Array,每一行是一个 ...

  5. eclipse和myeclipse怎么在项目中查找指定代码?https://www.jb51.net/softjc/554889.html

    有的童鞋,想eclipse和myeclipse整个项目中查找指定代码,由于补经常使用,可能会补熟悉.如果要去掉项目中所有的某个代码的话,找不到是灰常麻烦的,下面就简单说下怎么查找,希望对需要的人有用. ...

  6. springMVC+Spring+Mybatis+Redis

    SPRINGMVC+MYBATIS+SPRING+REDIS 只作参考,以防忘记使用! mybatis的配置文件: <?xml version="1.0" encoding= ...

  7. 【HANA系列】SAP HANA SQL获取上周的周一

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA SQL获取上周 ...

  8. Scratch少儿编程系列:(六)诗词《从军行》赏析

    一.程序说明 本程序用来显示<从军行>诗词,逐字显示.本来计划用2.0制作,但在制作过程中,在“造型”中无法输入汉字,临时采用3.0版本,1.4版本也可以. 二.程序流程图 为了更直观的描 ...

  9. idea中怎么去查看maven项目的依赖包是否有冲突

    1:快捷键:

  10. Redis-集群操作

    一.查看集群状态 1.查看集群状态 /opt/redis/src/redis-cli -h 本机IP -p redsi实例端口 -c #连接redis实例 /opt/redis/src/redis-c ...