题目链接

戳我

\(Describe\)

有一场舞会,n个男生,n个女生,要组成n对舞伴,男生i和女生j组队的适合度是\(a_{ij}\),

不适合度是\(b_{ij}\),

让你求\(max(\sum(适合度)/\sum(不适合度))\)

\(Solution\)

这道题是\(01\)分数规划的好题目。我们首先拆分这个式子:

令\(A_i\)为舞伴的适合度,\(B_i\)为不适合度

\[C=\sum_{i=1}^{i<=n}a_i/\sum_{i=1}^{i<=n}b_i
\]

\[\sum_{i=1}^{i<=n}a_i=\sum_{i=1}^{i<=n}b_i*C
\]

\[\sum_{i=1}^{i<=n}a_i-\sum_{i=1}^{i<=n}b_i*C=0
\]

则我们可以对C二分一个数\(mid\)

\[令:ans=max(\sum_{i=1}^{i<=n}a_i-\sum_{i=1}^{i<=n}b_i*mid)
\]

如果\(ans>0\)则\(ans\)比\(C\)要小,反之比\(C\)大

那么这个\(max(ans)怎么求呢?\)

这个随便用个费用流搞一搞就好了;

  • 把每个人拆成\(x\)和\(x'\)
  • 将\(S\)和\(x\)相连,流量为1,费用为0
  • 将\(x'\)和\(T\)相连,流量为1,费用为0
  • 对于两个人\(x,y\)我们将\(x\)和\(y'\)相连,流量为1,费用为\(a[x][y]-mid*b[x][y]\)(因为我的spfa是跑的最短路,所以我写的是-a[x][y]+mid*b[x][y],最后跑出来的答案的绝对值就是最大费用最大流);
  • 跑一遍最大费用最大流

\(Code\)

#include<bits/stdc++.h>
using namespace std;
const double inf=1e9+7;
typedef long long ll;
int read(){
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9')
f=(c=='-')?-1:1,c=getchar();
while(c>='0'&&c<='9')
x=x*10+c-'0',c=getchar();
return x*f;
}
struct node{
int to,next,v;
double w;
}a[1000001];
int f[10001],pre[10001],fa[10001],s,t=1000,head[10001],cnt;
double dis[10001];
void add(int x,int y,int c,double v){
a[++cnt].to=y,a[cnt].next=head[x],a[cnt].v=c,a[cnt].w=v,head[x]=cnt;
a[++cnt].to=x,a[cnt].next=head[y],a[cnt].v=0,a[cnt].w=-v,head[y]=cnt;
}
queue<int>q;
int spfa(){
q.push(s);
for(int i=s;i<=t;i++)
dis[i]=inf;
memset(f,0,sizeof(f));
f[s]=1,dis[s]=0;
while(!q.empty()){
int now=q.front();
q.pop();
f[now]=0;
for(int i=head[now];i;i=a[i].next){
int v=a[i].to;
if(dis[v]>dis[now]+a[i].w&&a[i].v){
dis[v]=dis[now]+a[i].w,pre[v]=i,fa[v]=now;
if(!f[v])
f[v]=1,q.push(v);
}
}
}
if(dis[t]!=inf)
return 1;
return 0;
}
double ans1,ans;
void anser(){
ans=0,ans1=0;
while(spfa()){
int minx=2147483647;
for(int i=t;i!=s;i=fa[i])
minx=min(minx,a[pre[i]].v);
ans+=minx,ans1+=dis[t]*minx;
for(int i=t;i!=s;i=fa[i])
a[pre[i]].v-=minx,(pre[i]%2)?a[pre[i]+1].v+=minx:a[pre[i]-1].v+=minx;
}
}
double A[1001][1001],B[1001][1001];
int n;
bool check(double x){
memset(head,0,sizeof(head)),cnt=0;
for(int i=1;i<=n;i++)
add(s,i,1,0),add(i+n,t,1,0);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
add(i,j+n,1,-A[i][j]+x*B[i][j]);
}
anser();
return (-ans1)>=0;
}
int main(){
n=read();
double l=0,r=10000,maxx=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>A[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>B[i][j];
while(r-l>=1e-7){
double mid=(l+r)*0.5;
if(check(mid))
l=mid,maxx=max(maxx,mid);
else r=mid;
}
printf("%0.6lf",maxx);
}

「SDOI2017」新生舞会的更多相关文章

  1. LibreOJ 2003. 「SDOI2017」新生舞会 基础01分数规划 最大权匹配

    #2003. 「SDOI2017」新生舞会 内存限制:256 MiB时间限制:1500 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  2. LibreOJ #2003. 「SDOI2017」新生舞会

    内存限制:256 MiB 时间限制:1500 ms 标准输入输出 题目类型:传统 评测方式:文本比较 上传者: 匿名 01分数规划(并不知道这是啥..) km或费用流(并不会)验证 屠龙宝刀点击就送 ...

  3. loj2003 「SDOI2017」新生舞会

    分数规划+KM 算法 这个KM不好,看算法竞赛进阶指南的 #include <iostream> #include <cstring> #include <cstdio& ...

  4. 「SDOI2017」树点涂色 解题报告

    「SDOI2017」树点涂色 我sb的不行了 其实一开始有一个类似动态dp的想法 每个点维护到lct树上到最浅点的颜色段数,然后维护一个\(mx_{0,1}\)也就是是否用虚儿子的最大颜色 用个set ...

  5. AC日记——「SDOI2017」序列计数 LibreOJ 2002

    「SDOI2017」序列计数 思路: 矩阵快速幂: 代码: #include <bits/stdc++.h> using namespace std; #define mod 201704 ...

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

    新生舞会 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 学校组织了一次新生舞会,Cathy ...

  7. Unique -「企划」新生守则(?

    随想随记,主要是整活. 红色贝雷帽大爷会在校园不定期游走,遇见记得打招呼. 面食堂冰沙类饮品请快速解决或者边喝边搅,如果发现饮品甜度骤减请快速前往最近的垃圾桶扔掉. 关于散养猫小黄和小黑. 如果看见小 ...

  8. 【LOJ 2004】「SDOI2017」硬币游戏

    LOJ 2004 100pts 首先我们肯定要建AC自动机的.. 那么这题就肯定是个AC自动机上\(dp\). 所以想想状态. 首先如果我们把状态设成这样行不行: \(dp(i)\)表示匹配到了i节点 ...

  9. loj#2002. 「SDOI2017」序列计数(dp 矩阵乘法)

    题意 题目链接 Sol 质数的限制并没有什么卵用,直接容斥一下:答案 = 忽略质数总的方案 - 没有质数的方案 那么直接dp,设\(f[i][j]\)表示到第i个位置,当前和为j的方案数 \(f[i ...

随机推荐

  1. python开发IO模型:阻塞&非阻塞&异步IO&多路复用&selectors

    一 IO模型介绍 为了更好地了解IO模型,我们需要事先回顾下:同步.异步.阻塞.非阻塞 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非 ...

  2. 取当前时间,格式为,yyyy-mm-dd hh:mm:ss

    function CurentTime() { var now = new Date(); var year = now.getFullYear(); //年 var month = now.getM ...

  3. Jquery改变td内容为1的颜色

    Jquery改变td内容为1的颜色<table id="tb" > <tr> <td val="1">1</td> ...

  4. mysql 添加字段、删除字段、调整字段顺序

    用过MySQL的朋友,可能都在使用phpMyAdmin,我从2003年开始使用,感觉那东西适合远程mysql管理,并 不适合单机.单数据库的管理操作,特别是开发使用. 给家推荐一个软件管理mysql数 ...

  5. 时区时差换算(GMT,UTC,PST,PDT)

    2014年美国冬令时标准时间Stardand Time于11月2号开始实施,直到2015年3月8号为止. 冬令时,是指在冬天使用的标准时间.在使用日光节约时制(夏令时)的地区,夏天时钟拨快一小时,冬天 ...

  6. 概览JVM的基本结构和JVM内存结构

    概览JVM的基本结构和JVM的内存结构 这里概要介绍一下JVM在启动后,作为操作系统的一个进程的基本结构,以及从操作系统角度看,JVM如何管理它从操作系统里申请来的内存的,也就是JVM的内存结构或者叫 ...

  7. linux的基本指令--第三节

    查找与检索: 一.文件名查找:find . -name "test*"      find 路径  查找类型  名字  未输入路径则默认当前路径 二 . 内容检索:grep  &q ...

  8. PyCharm设置Ipython交互环境和宏快捷键进行数据分析图文详解

    使用Python进行数据分析,大家都会多少学习一本经典教材<利用Python进行数据分析>,书中作者使用了Ipython的交互环境进行了书中所有代码的案例演示,而书中的Ipython交互环 ...

  9. [转] const T、const T*、T *const、const T&、const T*& 的区别

    这里的T指的是一种数据类型,可以是int.long.doule等基本数据类型,也可以是自己类型的类型class.单独的一个const你肯定知道指的是一个常量,但const与其他类型联合起来的众多变化, ...

  10. MyBatis之 逆向工程生成代码

    逆向工程: 所谓mybatis逆向工程,就是mybatis会根据我们设计好的数据表,自动生成pojo.mapper以及mapper.xml. 工程简单案例: 1,新建一个java项目,把需要使用的ja ...