分数规划,最大费用最大流#

题意可以简化为给出一个矩阵,要求每行和每列必须且只能取一个格子,要求\(sigma\ a_{i,j}/sigma\ b_{i,j}\) 最大

考虑分数规划,可以将式子转化:

\(sigma\ a_{i,j}/sigma\ b_{i,j}=C\)

\(sigma\ a_{i,j}=sigma\ b_{i,j}*C\)

\(sigma\ a_{i,j}-sigma\ b_{i,j}*C=0\)

\(sigma(\ a_{i,j}-b_{i,j}*C)=0\)

C就是我们要求的最大值,我们可以\(mid\)实数二分它,对于每一个\(mid\),求出这种情况下\(sigma(\ a_{i,j}-b_{i,j}*mid)=0\)的最大值,如果最大值小于0,就说明\(mid>C\),反之亦然。

至于怎么求最大值,可以将横坐标建一个点集,纵坐标建一个点集,对于每个矩阵上的点\(a_{i,j}\)建一条从i到j的弧,流量为1,费用为\(a_{i,j}-sigma\ b_{i,j}*mid\),然后跑最大费用最大流就行了

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#define inf 0x7fffffff
using namespace std;
inline int read()
{
int ans=0,fh=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
fh=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
ans=(ans<<1)+(ans<<3)+ch-'0',ch=getchar();
return ans*fh;
}
const int maxn=300;
const int maxm=10010;
const double eps=0.00000001;
int s,t,v[maxm*2],u[maxm*2],w[maxm*2],qq[maxn],ll[maxn],nex[maxm*2],head[maxn],num=1,n,a[110][110],b[110][110];
double f[maxm*2],bj[maxn],l,r,mid;
bool cz[maxn];
queue<int>q;
void add(int x,int y,double fee)
{
u[++num]=x;
v[num]=y;
w[num]=1;
f[num]=fee;
nex[num]=head[x];
head[x]=num;
u[++num]=y;
v[num]=x;
w[num]=0;
f[num]=-fee;
nex[num]=head[y];
head[y]=num;
}
bool spfa()
{
memset(qq,0,sizeof(qq));
for(int i=1;i<=n*2+2;i++)
bj[i]=2100000000;
memset(ll,0,sizeof(ll));
q.push(s);
bj[s]=0;
ll[s]=inf;
while(!q.empty())
{
int now=q.front();
q.pop();
cz[now]=0;
for(int i=head[now];i;i=nex[i])
if(w[i]&&bj[v[i]]>bj[now]+f[i])
{
bj[v[i]]=bj[now]+f[i];
ll[v[i]]=min(w[i],ll[now]);
qq[v[i]]=i;
if(!cz[v[i]])
q.push(v[i]),cz[v[i]]=1;
}
}
return qq[t]>0;
}
double EK()
{
double fee=0;
while(spfa())
{
int liu=ll[t];
for(int i=qq[t];i;i=qq[u[i]])
w[i]-=liu,w[i^1]+=liu;
fee+=liu*bj[t];
}
return fee*-1;
}//最大费用最大流
double work(double x)
{
memset(head,0,sizeof(head));
num=1;
for(int i=1;i<=n;i++)
add(s,i,0),add(i+n,t,0);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
add(i,j+n,(double)x*b[i][j]-a[i][j]);//建图
return EK();
}
int main()
{
n=read();
s=n*2+1;t=s+1;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
a[i][j]=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
b[i][j]=read();
r=1000000;
while(r-l>eps)
{
mid=(l+r)*0.5;
double dd=work(mid);
if(dd>=0)
l=mid;
else
r=mid;
}//实数二分
printf("%.6lf",l);
fclose(stdin);
return 0;
}

Luogu-3705 [SDOI2017]新生舞会的更多相关文章

  1. BZOJ 4819 Luogu P3705 [SDOI2017]新生舞会 (最大费用最大流、二分、分数规划)

    现在怎么做的题都这么水了.. 题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=4819 (luogu) https://ww ...

  2. 洛谷3705 [SDOI2017] 新生舞会 【01分数规划】【KM算法】

    题目分析: 裸题.怀疑$ O(n^4log{n}) $跑不过,考虑Edmonds-Karp优化. 代码: #include<bits/stdc++.h> using namespace s ...

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

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

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

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

  5. 洛谷 P3705 [SDOI2017]新生舞会 解题报告

    P3705 [SDOI2017]新生舞会 题目描述 学校组织了一次新生舞会,\(Cathy\)作为经验丰富的老学姐,负责为同学们安排舞伴. 有\(n\)个男生和\(n\)个女生参加舞会买一个男生和一个 ...

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

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

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

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

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

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

  9. 【算法】01分数规划 --- HNOI2009最小圈 & APIO2017商旅 & SDOI2017新生舞会

    01分数规划:通常的问法是:在一张有 \(n\) 个点,\(m\) 条边的有向图中,每一条边均有其价值 \(v\) 与其代价 \(w\):求在图中的一个环使得这个环上所有的路径的权值和与代价和的比率最 ...

  10. 4819: [Sdoi2017]新生舞会(分数规划)

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

随机推荐

  1. Struts2学习之拦截器栈

    © 版权声明:本文为博主原创文章,转载请注明出处 拦截器栈: - 从结构上看:拦截器栈相当于多个拦截器的组合 - 从功能上看:拦截器栈也是拦截器 默认拦截器栈: - 在struts-core.jar中 ...

  2. SpringSecurity学习三----------通过Security标签库简单显示视图

    © 版权声明:本文为博主原创文章,转载请注明出处 1.项目结构 2.pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0& ...

  3. Atitit. 如何判断软件工程师 能力模型 程序员能力模型  项目经理能力模型

    Atitit. 如何判断软件工程师 能力模型 程序员能力模型  项目经理能力模型 这里能力模型的标准化是对工具的使用为基本 工具(ide,语言,类库,框架,软件) 第一步 ::可使用api 类库 框架 ...

  4. Python基础之初识递归

    初识递归 递归的定义: 在一个函数里再调用这个函数本身,这种魔性的使用函数的方式就叫做递归. 递归的最大深度--997 递归函数不受外力的阻止会一直执行下去,python为了杜绝此类现象,强制将递归层 ...

  5. 基于JT/T 1078协议设计和开发部标视频服务器

    交通部与2016年10月份推出了JT/T 1078-2016标准,全称是<道路运输车辆卫星定位系统视频通信协议>.该标准将改变以往两客一危车辆的视频监控设备通信协议都是设备厂商私有协议的局 ...

  6. Monkey源代码分析之事件源

    上一篇文章<Monkey源代码分析之执行流程>给出了monkey执行的整个流程.让我们有一个概貌,那么往后的文章我们会尝试进一步的阐述相关的一些知识点. 这里先把整个monkey类的结构图 ...

  7. 基于markdown的blog系统调研1:typecho

    ))

  8. HTML5 - 新增的元素,删除的元素

    1,HTML5新增的元素(1)用于构建页面的语义元素:<article>,<aside>,<figcaption>,<figure>,<foote ...

  9. c_str()方法使用

    语法: const char *c_str(); c_str()函数返回一个指向正规C字符串的指针常量, 内容与本string串相同. 这是为了与c语言兼容,在c语言中没有string类型,故必须通过 ...

  10. windowsphone8.1学习笔记之位图编程

    说位图,先把image控件简单过下,Image的Source设置 <Image Name="img" Source="可以是网络图片的Uri.应用文件的Uri或者安 ...