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

题意可以简化为给出一个矩阵,要求每行和每列必须且只能取一个格子,要求\(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. Resharper快捷键及用法

    建议你使用 Reshaper 的快捷键,不要担心 Reshaper 会把你原来的快捷键设置给覆盖了,因为如果某个快捷键和 VS 是冲突的,Reshaper会让你自己选择需要使用 VS 还是 Resha ...

  2. sklearn函数白板

    #使用make_classification构造500个样本,每个样本有20个feature from sklearn.datasets import make_classification X, y ...

  3. SetTimer时间间隔的问题

    1.用WM_TIMER来设置定时器   SetTimer函数的原型 UINT_PTR SetTimer( HWND hWnd,                      // 窗体句柄 UINT_PT ...

  4. docker-maven-plugin

    顾名思义,docker-maven-plugin是一个docker的maven插件,用来执行docker镜像的制作和上传,他的地址是https://github.com/spotify/docker- ...

  5. Ueditor编辑器图片上传到万象优图

    最近想用typecho做一个个人博客站,typecho的文本编辑器不能上传图片,我就用Ueditor替换的了原来的文本编辑器,听说腾讯的万象优图每月有50G的免费空间和流量,我就自己改了下Uedito ...

  6. C# 代码 手工 配置 Log4Net 2种方法

    这个初始化要在 获取 ILog 接口的代码之前完成, 之后按通常方式使用 log4net 就行了. 不用携带 config 配置文件. 方法1: /// <summary> /// 使用文 ...

  7. 自定义WPF ListBox的选择样式

    (下图:进行多项选择的ListBox) 首先介绍一种简单地方法:就是通过自定义SystemColors类的参数来自定义WPF ListBox选择颜色的,SystemColors的HighlightBr ...

  8. ASP.NET动态网站制作(15)-- SQL数据库(1)

    前言:数据库(Database)是按照数据结构来组织.存储和管理数据的仓库,用户可以对文件中的数据进行增.删.改.查.数据库有很多种类型,从简单的存储有各种数据的表格到能都进行海量数据存储的大型数据库 ...

  9. wordcloud使用

    学了下怎么用wordcloud. 以imet的数据集为例 https://www.kaggle.com/c/imet-2019-fgvc6 读取“train.csv”,”label.csv”文件,得到 ...

  10. elasticsearch从入门到出门-02-简单的CRUD

    操作背景: 电商网站上面的一个商品的增删改查: es 能接受的都是JSON格式的数据 Es 提供了一套简单的集群信息健康监控的api GET /_cat/health?v   epoch      t ...