4819: [Sdoi2017]新生舞会

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 1031  Solved: 530
[Submit][Status][Discuss]

Description

学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴。有n个男生和n个女生参加舞会
买一个男生和一个女生一起跳舞,互为舞伴。Cathy收集了这些同学之间的关系,比如两个人之前认识没计算得出 
a[i][j] ,表示第i个男生和第j个女生一起跳舞时他们的喜悦程度。Cathy还需要考虑两个人一起跳舞是否方便,
比如身高体重差别会不会太大,计算得出 b[i][j],表示第i个男生和第j个女生一起跳舞时的不协调程度。当然,
还需要考虑很多其他问题。Cathy想先用一个程序通过a[i][j]和b[i][j]求出一种方案,再手动对方案进行微调。C
athy找到你,希望你帮她写那个程序。一个方案中有n对舞伴,假设没对舞伴的喜悦程度分别是a'1,a'2,...,a'n,
假设每对舞伴的不协调程度分别是b'1,b'2,...,b'n。令
C=(a'1+a'2+...+a'n)/(b'1+b'2+...+b'n),Cathy希望C值最大。
 

Input

第一行一个整数n。
接下来n行,每行n个整数,第i行第j个数表示a[i][j]。
接下来n行,每行n个整数,第i行第j个数表示b[i][j]。
1<=n<=100,1<=a[i][j],b[i][j]<=10^4
 

Output

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

Sample Input

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

Sample Output

5.357143

分析

首先是分数规划,然后用费用流判断。

$c=\frac{a_1+a_2+...+a_k}{b_1+b_2+...+b_k}$

二分c,如果c满足条件,那么$a_1+a_2+...+a_k \geq c*(b_1+b_2+...+b_k)$

在转化一下$(a_1-c*b_1)+(a_2-c*b_2)...+(a_k-c*b_k) \geq 0$

那么如果选i,j,他们的贡献就是a[i][j]-c*b[i][j],建图跑最大费用流即可。

可以把贡献取负,然后跑最小流。

注意要开double的变量

code

 #include<cstdio>
#include<algorithm>
#include<cstring> using namespace std; const int N = ;
const int INF = 1e9;
const double eps = 1e-; struct Edge{
int from,to,nxt,cap;double cost;
}e[];
int head[N],q[],pre[N];
bool vis[N];
int tot = ,n,m,S,T;
int a[N][N],b[N][N];
double dis[N]; void add_edge(int u,int v,int cap,double cost) {
e[++tot].from = u;e[tot].to = v;e[tot].cap = cap;e[tot].cost = cost;e[tot].nxt = head[u];head[u] = tot;
e[++tot].from = v;e[tot].to = u;e[tot].cap = ;e[tot].cost = -cost;e[tot].nxt = head[v],head[v] = tot;
}
void Clear() {
tot = ;
memset(head,,sizeof(head));
}
bool spfa() {
for (int i=; i<=T; ++i)
dis[i] = INF,vis[i] = false;
dis[S] = ;vis[S] = true;pre[S] = ;
int L = ,R = ;
q[++R] = S;
while (L <= R) {
int u = q[L++];
for (int i=head[u]; i; i=e[i].nxt) {
int v = e[i].to;
if (e[i].cap && dis[v]-(dis[u]+e[i].cost)>=eps) {
dis[v] = dis[u] + e[i].cost;
pre[v] = i;
if (!vis[v]) q[++R] = v,vis[v] = true;
}
}
vis[u] = false;
}
if (dis[T] == INF) return false;
return true;
}
double MincostMaxflow() { // 返回double
double Mincost = ; // double类型
while (spfa()) {
int minflow = INF;
for (int i=T; i!=S; i=e[pre[i]].from)
minflow = min(minflow,e[pre[i]].cap);
for (int i=T; i!=S; i=e[pre[i]].from) {
e[pre[i]].cap -= minflow;
e[pre[i] ^ ].cap += minflow;
}
Mincost += minflow * dis[T];
}
return Mincost;
}
bool check(double x) {
Clear();
for (int i=; i<=n; ++i) add_edge(S,i,,);
for (int i=; i<=n; ++i) add_edge(i+n,T,,);
for (int i=; i<=n; ++i)
for (int j=; j<=n; ++j)
add_edge(i,j+n,,-(a[i][j]-1.0*x*b[i][j]));
double ans = MincostMaxflow();
return ans <= ;
}
int main () {
scanf("%d",&n);
for (int i=; i<=n; ++i)
for (int j=; j<=n; ++j)
scanf("%d",&a[i][j]);
for (int i=; i<=n; ++i)
for (int j=; j<=n; ++j)
scanf("%d",&b[i][j]);
S = n*+;T = n*+;
double L = 0.0,R = 10000.0,ans;
while (R-L >= eps) {
double mid = (L + R) / ;
if (check(mid)) ans = mid,L = mid;
else R = mid;
}
printf("%.6lf",ans);
return ;
}

4819: [Sdoi2017]新生舞会(分数规划)的更多相关文章

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

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

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

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

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

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

  4. bzoj4819 [Sdoi2017]新生舞会 分数规划+最大费用最大流

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4819 题解 首先上面说, \[ C = \frac{\sum\limits_{i=1}^n a ...

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

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

  6. 【BZOJ 4819】 4819: [Sdoi2017]新生舞会 (0-1分数规划、二分+KM)

    4819: [Sdoi2017]新生舞会 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 601  Solved: 313 Description 学校 ...

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

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

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

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

  9. bzoj 4819: [Sdoi2017]新生舞会

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

随机推荐

  1. iQuery stop()

    jQuery stop() 方法 jQuery stop() 方法用于停止动画或效果,在它们完成之前. stop() 方法适用于所有 jQuery 效果函数,包括滑动.淡入淡出和自定义动画. 语法 $ ...

  2. tas5717/5719功放问题点总结

    问题一 AMP output channel invert problem and modification 原因:如果硬件设计时,耳机或者喇叭的输出通道反了,就要对其进行左右对换. 对策:如果通道反 ...

  3. uLua学习之读取外部Lua脚本(四)

    前言 上节说到了Lua脚本与unity3d中C#脚本的数据交互,但是我感觉上节中的数理方式不太好,因为我们是把Lua脚本以字符串形式粘贴到C#脚本中的,如果读取配置数据都这样做的话,那就太可怕了.想想 ...

  4. 不该被忽视的CoreJava细节(一)

    一.系列文章导言 <不该被忽视的CoreJava细节>系列文章将会持续更新.我希望自己通过这一系列文章的写作,能与读者一起进步,逐步完善对Java体系结构的了解. 二.本期关注点 几乎翻看 ...

  5. redis在Windows下以后台服务一键搭建集群(多机器)

    redis在Windows下以后台服务一键搭建集群(多机器) 一.概述 此教程介绍如何在windows系统中多台机器之间布置redis集群,同时要以后台服务的模式运行.布置以脚本的形式,一键完成.多台 ...

  6. LeetCode Add Two Numbers 两个数相加

    /** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode ...

  7. 富文本编辑器Ueditor的使用

    1.下载:http://ueditor.baidu.com/website/download.html. 2.解压,并放到项目webapp下. 3.jsp页面的配置. 4.配置根路径. 5.页面展示: ...

  8. 【BZOJ2427】[HAOI2010] 软件安装(缩点+树形DP)

    点此看题面 大致题意: 有\(N\)个软件,每个软件有至多一个依赖以及一个所占空间大小\(W_i\),只有当一个软件的直接依赖和所有的间接依赖都安装了,它才能正常工作并造成\(V_i\)的价值.求在容 ...

  9. Linux常用的200个命令总结分类

    ●目录操作命令(6 个) ls tree pwd mkdir rmdir cd   ●文件操作命令(7 个) touch cp mv rm ln find rename   ●文件查看及处理命令(21 ...

  10. Redis学习记录(一)

    在学习Redis之前,要知道什么是NoSQL? 1.NoSQL 1.1. 什么是NoSQL NoSQL(NoSQL = Not Only SQL),表示“不仅仅是SQL”,泛指非关系型数据库. 1.2 ...