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

题意可以简化为给出一个矩阵,要求每行和每列必须且只能取一个格子,要求\(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. zoj 3827 Information Entropy 【水题】

    Information Entropy Time Limit: 2 Seconds      Memory Limit: 65536 KB      Special Judge Information ...

  2. jquery的eq()

    jQuery 遍历 - eq() 方法 jQuery 遍历参考手册 实例 通过为 index 为 2 的 div 添加适当的类,将其变为蓝色: $("body").find(&qu ...

  3. 小技巧之Selenium如何切换到弹出的Tab页中

    今天群里讨论了一个问题,如何将selenium的操作焦点切换到浏览器中新弹出来的Tab页中,正好对应到了昨天的那篇文章“小技巧之在浏览器中打开新的页签”.今天就带大家来解决这个问题: 先封装一个Tab ...

  4. db2 error

    DB2 SQL Error: SQLCODE=-668, SQLSTATE=57016, SQLERRMC=7;MCD_BJ.MTL_CHANNEL_DEF, DRIVER=4.18.60 你的表处于 ...

  5. android-support-v4.jar异常解决方法

    1.当一个项目引入其他library项目时,会出现android-support-v4.jar冲突问题: 解决:将library项目中的android-support-v4.jar更新到最新,方法右键 ...

  6. 全文检索引擎Solr的配置

    描述: 在Linux环境下实现高速的全文检索 一.当前环境: CentOS (Linux) 6.3 64 bit 二.所需软件 1.Java的JDK Java jdk 1.7.0[注意:solr5.x ...

  7. 在Linux先显示文件

    cat:从第一行开始显示文件内容. tac:从最后一行开始显示内容. nl:显示的时候带行号. more:一页一页显示. less:同more,可以向上翻页. head:显示文件前几行. head - ...

  8. iptables基础及samba配置举例

    iptable基本概念 iptables防火墙包含两部分,即位于用户空间的iptables模块和位于内核空间netfilter模块.用户空间模块提供插入.修改和除去包过滤表中规则,内核模块进行实际的过 ...

  9. RecyclerView的使用(3)之加入Header和Footer

    原创文章.转载请注明 http://blog.csdn.net/leejizhou/article/details/50742544 李济洲的博客 RecyclerView尽管作为ListView的替 ...

  10. ios上ZXing库的配置流程

    本文转载至 http://blog.csdn.net/louercab/article/details/26448587 步骤 首先,用Xcode创建我们的demo, 取名TestZXing(根据自己 ...