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个女生参加舞会 买一个男生和一个女 ...
随机推荐
- jenkins不展示set Build Description Setter插件
问题描述: 1.jenkins 已下载 set build descripteion ,并且配置过,可以在构建历史中展示就用二维码 2.问题:构建历史中不展示二维码了,如图: 总是排查: 1.首先想到 ...
- Jenkins安装以及配置
Jenkins介绍 Jenkins是一个java开发的.开源的.非常好用持续集成的工具,它能帮我们实现自动化部署环境.测试.打包等等的工作,还可以在构建任务成功或者失败之后给我们发邮件通知. 什么叫持 ...
- C#接口的实现和继承实践
1.基本概念 接口是一种契约规范,类似于抽象基类.包括方法,属性,索引器和事件作为成员,这些成员只是作为定义,并不在接口中具体实现. 接口创建时注意以下事项: 继承接口的任何非抽象类都必须实现接口的所 ...
- lua源码学习篇三:赋值表达式解析的流程
上节说到表达式的解析问题,exprstate函数用于解析普通的赋值表达式.lua语言支持多变量赋值.本文先从单变量赋值表达式讲起. a = b = c = a + b 对于简单的两个数的求和过程,lu ...
- OpenStack 实现技术分解 (6) 通用库 — oslo_log
目录 目录 前文列表 扩展阅读 日志级别 oslolog 初始化设置 DEMO oslolog 的相关配置项 oslolog 的日志级别 oslolog 的使用技巧 推荐使用 LOGdebug 的地方 ...
- 分布式任务队列 Celery —— 深入 Task
目录 目录 前文列表 前言 Task 的实例化 任务的名字 任务的绑定 任务的重试 任务的请求上下文 任务的继承 前文列表 分布式任务队列 Celery 分布式任务队列 Celery -- 详解工作流 ...
- dcef3 指出一个坑
dcef3 指出一个坑 http://ju.outofmemory.cn/entry/80119 BccSafe's Blog 2014-06-11 2388 阅读 dcef3提供了TChromi ...
- HTML真是好东西!
HTML真是好东西! 学习HTML已经两天了,别小看这两天哦,这短短的两天估计要比学校的四周还要长.不仅有教学,还有同学与老师之间的交流,最重要的是自己上机实践的过程.在这个过程中,不仅知道了在HTM ...
- centos7配置NTP时间服务器
Network Time Protocol--NTP时间服务器,用来同步网络中各个计算机时间的协议. 通常将一台服务器配置为时间服务器,然后集群内其他服务器都来同步这台服务器的时间. 目的:集群内所有 ...
- JMeter常用的4种参数化方式-操作解析
目录结构 一.JMeter参数化简介 1.JMeter参数化的概念 2.JMeter参数化方式之使用场景对比 二.JMeter参数化的4种主要方式-操作演练 1.User Parameters(用户参 ...