$ \color{#0066ff}{ 题目描述 }$

学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴。

有\(n\)个男生和\(n\)个女生参加舞会买一个男生和一个女生一起跳舞,互为舞伴。

Cathy收集了这些同学之间的关系,比如两个人之前认识没计算得出 \(a_{i,j}\)

Cathy还需要考虑两个人一起跳舞是否方便,比如身高体重差别会不会太大,计算得出 \(b_{i,j}\),表示第i个男生和第j个女生一起跳舞时的不协调程度。

当然,还需要考虑很多其他问题。

Cathy想先用一个程序通过\(a_{i,j}\)和\(b_{i,j}\),j求出一种方案,再手动对方案进行微调。

Cathy找到你,希望你帮她写那个程序。

一个方案中有n对舞伴,假设没对舞伴的喜悦程度分别是\(a'_1,a'_2,...,a'_n\),假设每对舞伴的不协调程度分别是\(b'_1,b'_2,...,b'_n\)。令

\(C=\frac{a'_1+a'_2+...+a'_n}{b'_1+b'_2+...+b'_n}\)

Cathy希望C值最大。

\(\color{#0066ff}{输入格式}\)

第一行一个整数n。

接下来n行,每行n个整数,第i行第j个数表示\(a_{i,j}\)。

接下来n行,每行n个整数,第i行第j个数表示\(b_{i,j}\)。

\(\color{#0066ff}{输出格式}\)

一行一个数,表示C的最大值。四舍五入保留6位小数,选手输出的小数需要与标准输出相等。

\(\color{#0066ff}{输入样例}\)

3
19 17 16
25 24 23
35 36 31
9 5 6
3 4 2
7 8 9

\(\color{#0066ff}{输出样例}\)

5.357143

\(\color{#0066ff}{数据范围与提示}\)

对于10%的数据,\(1\le n\le 5\)

对于40%的数据,\(1\le n\le 18\)

另有20%的数据,\(b_{i,j}\le 1\)

对于100%的数据,\(1\le n\le 100,1\le a_{i,j},b_{i,j}<=10^4\)

\(\color{#0066ff}{题解}\)

很显然这是个01分数规划, 二分答案就行

考虑二分完之后咋整,要是新权值和最小(大), 二人一一对应, 用费用流就行了

注意二分范围
#include<bits/stdc++.h>
#define LL long long
LL in() {
char ch; LL x = 0, f = 1;
while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
return x * f;
}
const double eps = 1e-8;
const int maxn = 1e5 + 100;
const int maxm = 1020;
const int inf = 0x7fffffff;
int n, s, t;
struct node {
int to, can;
double dis;
node *nxt, *rev;
node(int to = 0, int can = 0, double dis = 0, node *nxt = NULL): to(to), can(can), dis(dis), nxt(nxt) { rev = NULL; }
}pool[maxn], *tail;
node *head[maxm];
bool vis[maxm];
double dis[maxm];
int a[maxm][maxm], b[maxm][maxm];
void init() {
for(int i = s; i <= t; i++) head[i] = NULL;
tail = pool;
}
void add(int from, int to, int can, double dis) {
head[from] = new(tail++) node(to, can, dis, head[from]);
}
void link(int from, int to, int can, double dis) {
add(from, to, can, dis), add(to, from, 0, -dis);
(head[from]->rev = head[to])->rev = head[from];
}
bool spfa() {
for(int i = s; i <= t; i++) vis[i] = false, dis[i] = 1e15;
std::deque<int> q;
dis[t] = 0;
q.push_back(t);
while(!q.empty()) {
int tp = q.front(); q.pop_front();
vis[tp] = false;
for(node *i = head[tp]; i; i = i->nxt) {
if(dis[i->to] - (dis[tp] - i->dis) > eps && i->rev->can) {
dis[i->to] = dis[tp] - i->dis;
if(!vis[i->to]) {
vis[i->to] = true;
if(!q.empty() && dis[q.front()] - dis[i->to] > eps) q.push_front(i->to);
else q.push_back(i->to);
}
}
}
}
return 1e15 - dis[s] > eps;
}
int dfs(int x, int change) {
if(x == t || !change) return change;
vis[x] = true;
int flow = 0, ls;
for(node *i = head[x]; i; i = i->nxt) {
if(!vis[i->to] && fabs(dis[i->to] - (dis[x] - i->dis)) <= eps && (ls = dfs(i->to, std::min(change, i->can)))) {
change -= ls;
flow += ls;
i->rev->can += ls;
i->can -= ls;
if(!change) break;
}
}
return flow;
}
double zkw() {
double cost = 0;
while(spfa()) {
vis[t] = true;
while(vis[t]) {
for(int i = s; i <= t; i++) vis[i] = false;
cost += 1.0 * dfs(s, inf) * dis[s];
}
}
return cost;
}
bool ok(double mid) {
s = 0, t = 2 * n + 1;
init();
for(int i = 1; i <= n; i++) link(s, i, 1, 0), link(i + n, t, 1, 0);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
link(i, j + n, 1, (double)(mid * b[i][j] - 1.0 * a[i][j]));
return zkw() <= -eps;
} int main() {
n = in();
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
a[i][j] = in();
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
b[i][j] = in();
double l = 0, r = 1e5, ans = 0;
while(r - l >= eps) {
double mid = (l + r) / 2.0;
if(ok(mid)) ans = mid, l = mid;
else r = mid;
}
printf("%.6f\n", ans);
return 0;
}

P3705 [SDOI2017]新生舞会 01分数规划+费用流的更多相关文章

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

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

  2. BZOJ.4819.[SDOI2017]新生舞会(01分数规划 费用流SPFA)

    BZOJ 洛谷 裸01分数规划.二分之后就是裸最大费用最大流了. 写的朴素SPFA费用流,洛谷跑的非常快啊,为什么有人还T成那样.. 当然用二分也很慢,用什么什么迭代会很快. [Update] 19. ...

  3. BZOJ_4819_[Sdoi2017]新生舞会_01分数规划+费用流

    BZOJ_4819_[Sdoi2017]新生舞会_01分数规划+费用流 Description 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴.有n个男生和n个女生参加舞 ...

  4. BZOJ-4819: 新生舞会(01分数规划+费用流)

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

  5. [Sdoi2017]新生舞会(分数规划+费用流)

    题解:二分答案mid,然后将每个位置看成a-b*mid,然后由于是n个男生和n个女生匹配,每个人搭配一个cp,于是有点类似于https://www.lydsy.com/JudgeOnline/prob ...

  6. [Sdoi2017]新生舞会 [01分数规划 二分图最大权匹配]

    [Sdoi2017]新生舞会 题意:沙茶01分数规划 貌似\(*10^7\)变成整数更科学 #include <iostream> #include <cstdio> #inc ...

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

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

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

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

  9. 【BZOJ4819】 新生舞会(01分数规划,费用流)

    Solution 考虑一下这个东西的模型转换: \(\frac{\sum_{i=1}^n{a_i}}{\sum_{i=1}^n{b_i}}\) 然后转换一下发现显然是01分数规划. \(\sum_{i ...

随机推荐

  1. leetcode728

    vector<int> selfDividingNumbers(int left, int right) { vector<int> V; for (int i = left; ...

  2. http头部信息解析

    HTTP 头部解释 1. Accept:告诉WEB服务器自己接受什么介质类型,*/* 表示任何类型,type/* 表示该类型下的所有子类型,type/sub-type. 2. Accept-Chars ...

  3. c# 如何制作RealPlayer 视频播放器

      c# 如何制作RealPlayer 视频播放器 主要介绍了如何使用 RealPlayer G2 Control 控件 那么我们怎么获得到这个控件呢,很简单,操作方法如下 右单击工具箱对话框的[所有 ...

  4. NOIP2018 解题笔记

    D1T1 铺设道路 在场上并没有想到积木大赛这道原题. 差分之后可以把在$[l, r]$这段区间$ - 1$变成在$l$处$ - 1$,在$r + 1$处$ + 1$,然后最终目标是使$\forall ...

  5. Luogu 2886 [USACO07NOV]牛继电器Cow Relays

    BZOJ 1706权限题. 倍增$floyd$. 首先这道题有用的点最多只有$200$个,先离散化. 设$f_{p, i, j}$表示经过$2^p$条边从$i$到$j$的最短路,那么有转移$f_{p, ...

  6. sed陷阱

    sed陷阱:   sed -i 后不要紧跟字母, 否则会产生一个新的备份文件(在原文件后多出来一个字母) // 正确写法 /usr/bin/sed -i "/PREFIX=/d" ...

  7. .Net插入大批量数据

    1. 使用SqlDataAdapter /// <summary>        /// 实现数据库事务,大批量新增数据        /// </summary>       ...

  8. 黑盒测试实践-任务进度-Day02

    使用工具 selenium 小组成员 华同学.郭同学.穆同学.沈同学.覃同学.刘同学 任务进度 在经过了昨天的基本任务分配之后,今天大家就开始了各自的内容,以下是大家任务的进度情况汇总. 华同学(任务 ...

  9. Linux基础-工作中经常使用到的linux 命令

     linux 常用命令 (1)命令ls——列出文件 ls -la 给出当前目录下所有文件的一个长列表,包括以句点开头的“隐藏”文件 ls a* 列出当前目录下以字母a开头的所有文件 ls -l *.d ...

  10. C++初始化,之不明白篇 cout<<x<<endl 与 cout<<"x = "<<cout<<x<<endl的输出的值会不一样

    代码如下 #include <iostream> using namespace std; class point { public :     int x;     int y;     ...