bzoj4819 [Sdoi2017]新生舞会 分数规划+最大费用最大流
题目传送门
https://lydsy.com/JudgeOnline/problem.php?id=4819
题解
首先上面说,
\]
要 \(C\) 最大。这是一种非常常见的分数规划模型,于是二分后转化成
\]
于是问题转化为求出权值和最大的方案满足每个人只选择一次。
可以是一个二分图匹配的模型,所以可以转化为最大费用最大流完成。
时间复杂度很玄学,不知道为什么能过。
调了半年的最小费用最大流突然想起来应该维护最大费用最大流。
#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]新生舞会 分数规划+最大费用最大流的更多相关文章
- [BZOJ4819][SDOI2017]新生舞会(分数规划+费用流,KM)
4819: [Sdoi2017]新生舞会 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1097 Solved: 566[Submit][Statu ...
- 【bzoj4819】[Sdoi2017]新生舞会 分数规划+费用流
题目描述 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴.有n个男生和n个女生参加舞会买一个男生和一个女生一起跳舞,互为舞伴.Cathy收集了这些同学之间的关系,比如两个 ...
- 4819: [Sdoi2017]新生舞会 分数规划
题目 https://www.lydsy.com/JudgeOnline/problem.php?id=4819 思路 分数规划的模板题?(好菜呀) 假如n=3吧(懒得写很长的式子) \(c=\fra ...
- P3705 [SDOI2017]新生舞会 分数规划 费用流
#include <algorithm> #include <iterator> #include <iostream> #include <cstring& ...
- bzoj 4819: [Sdoi2017]新生舞会【二分+最小费用最大流】
如果\( b[i]==0 \)那么就是裸的费用流/KM,当然KM快一些但是为什么不写KM呢因为我不会打板子了 考虑二分答案,那么问题变成了判定问题. \[ ans=\frac {a_1+a_2+... ...
- BZOJ4819 [Sdoi2017]新生舞会 【01分数规划 + 费用流】
题目 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴.有n个男生和n个女生参加舞会 买一个男生和一个女生一起跳舞,互为舞伴.Cathy收集了这些同学之间的关系,比如两个人 ...
- BZOJ4819: [Sdoi2017]新生舞会(01分数规划)
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1029 Solved: 528[Submit][Status][Discuss] Descripti ...
- bzoj4819 [Sdoi2017]新生舞会
Description 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴.有n个男生和n个女生参加舞会买一个男生和一个女生一起跳舞,互为舞伴.Cathy收集了这些同学之间的 ...
- 【BZOJ4819】[Sdoi2017]新生舞会 01分数规划+费用流
[BZOJ4819][Sdoi2017]新生舞会 Description 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴.有n个男生和n个女生参加舞会 买一个男生和一个女 ...
随机推荐
- python学习笔记:(二)基本数据类型
python中的变量不需要声明,每个变量中使用前都必须赋值,变量赋值以后该变量才会被创建. 在python中变量就是变量,他没有类型,我们所说的类型是变量所指的内存中对象的类型. python3中有六 ...
- 【MM系列】SAP MM模块-查看移动平均价的历史记录
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[MM系列]SAP MM模块-查看移动平均价的历 ...
- cocos2dx基础篇(20) 扩展动作CCGridAction
[3.x] (1)去掉"CC" [CCGridAction] CCGridAction有两个子类:CCGrid3DAction.CCTiledGrid3DAction.而我 ...
- 应用安全 - Java Web 应用 - Confluence - 漏洞汇总
CVE-2019-3395 Date: -- 类型: SSRF 影响范围: Confluence 1.*.*.*.*.3.*.*.4.*.*.5.*.* Confluence 6.0.*.1.*.6. ...
- 【Linux开发】【Qt开发】配置tslibs触摸屏库环境设置调试对应的设备挂载点
[Linux开发][Qt开发]配置tslibs触摸屏库环境设置调试对应的设备挂载点 标签(空格分隔): [Linux开发] [Qt开发] 比如: cat /dev/input/mice cat /de ...
- 红帽学习笔记[RHCSA] 第九课[文件归档、硬盘、分区以及自动挂载、Swap、链接]
文件归档 tar是什么 通过tar命令可以将大型文件汇集成一个文件(归档),注意没有压缩功能. 压缩方式 gzip 通过gzip过滤文档,使用最广泛 bzip2 通常比gzip压缩小,但是不如gzip ...
- 《剑指offer》面试题25 二叉树中和为某一值的路径 Java版
(判断是否有从根到叶子节点的路径,其和为给定值.记录这些路径.) 我的方法:这道题我是按照回溯的思路去做的,我们需要一个数据结构来保存和删除当前递归函数中添加的值.这里要打印一条路径,我们可以选择Li ...
- windows上安装 包管理工具choco及scoop
1.安装 choco: 1.1.使用管理员方式打开 PowerShell 1.2.输入 Set-ExecutionPolicy RemoteSigned,输入 Y 1.3.安装 choco输入:iwr ...
- C++ static、const和static const类型成员变量声明以及初始化
C++ static.const和static const 以及它们的初始化 const定义的常量在超出其作用域之后其空间会被释放,而static定义的静态常量在函数执行后不会释放其存储空间. sta ...
- px-em-pt等字体的不同