Luogu-3705 [SDOI2017]新生舞会
分数规划,最大费用最大流#
题意可以简化为给出一个矩阵,要求每行和每列必须且只能取一个格子,要求\(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]新生舞会的更多相关文章
- BZOJ 4819 Luogu P3705 [SDOI2017]新生舞会 (最大费用最大流、二分、分数规划)
现在怎么做的题都这么水了.. 题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=4819 (luogu) https://ww ...
- 洛谷3705 [SDOI2017] 新生舞会 【01分数规划】【KM算法】
题目分析: 裸题.怀疑$ O(n^4log{n}) $跑不过,考虑Edmonds-Karp优化. 代码: #include<bits/stdc++.h> using namespace s ...
- [Sdoi2017]新生舞会 [01分数规划 二分图最大权匹配]
[Sdoi2017]新生舞会 题意:沙茶01分数规划 貌似\(*10^7\)变成整数更科学 #include <iostream> #include <cstdio> #inc ...
- BZOJ_4819_[Sdoi2017]新生舞会_01分数规划+费用流
BZOJ_4819_[Sdoi2017]新生舞会_01分数规划+费用流 Description 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴.有n个男生和n个女生参加舞 ...
- 洛谷 P3705 [SDOI2017]新生舞会 解题报告
P3705 [SDOI2017]新生舞会 题目描述 学校组织了一次新生舞会,\(Cathy\)作为经验丰富的老学姐,负责为同学们安排舞伴. 有\(n\)个男生和\(n\)个女生参加舞会买一个男生和一个 ...
- 【BZOJ 4819】 4819: [Sdoi2017]新生舞会 (0-1分数规划、二分+KM)
4819: [Sdoi2017]新生舞会 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 601 Solved: 313 Description 学校 ...
- 【BZOJ4819】[Sdoi2017]新生舞会 01分数规划+费用流
[BZOJ4819][Sdoi2017]新生舞会 Description 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴.有n个男生和n个女生参加舞会 买一个男生和一个女 ...
- [BZOJ4819][SDOI2017]新生舞会(分数规划+费用流,KM)
4819: [Sdoi2017]新生舞会 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1097 Solved: 566[Submit][Statu ...
- 【算法】01分数规划 --- HNOI2009最小圈 & APIO2017商旅 & SDOI2017新生舞会
01分数规划:通常的问法是:在一张有 \(n\) 个点,\(m\) 条边的有向图中,每一条边均有其价值 \(v\) 与其代价 \(w\):求在图中的一个环使得这个环上所有的路径的权值和与代价和的比率最 ...
- 4819: [Sdoi2017]新生舞会(分数规划)
4819: [Sdoi2017]新生舞会 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1031 Solved: 530[Submit][Statu ...
随机推荐
- leetCode 50.Pow(x, n) (x的n次方) 解题思路和方法
Pow(x, n) Implement pow(x, n). 思路:题目不算难.可是须要考虑的情况比較多. 详细代码例如以下: public class Solution { public doubl ...
- left join,right join用法简介
方法一(推荐): select a.man_id,man_name,d.sex_name,zw_name,c.money from man as a left join zw as b on a.zw ...
- 为什么要用markdown写作
无论是 EPUB, mobi,还是 Kindle 用的专有格式 .azw,都只是把一堆 `HTML 文件打包`而已.如果你写的是书,用 Markdown 标注格式之后,可以很方便地转为以上格式 使用W ...
- web安全之SQL注入---第三章 如何寻找sql注入?
借助逻辑推理1.识别web应用中所有输入点2.了解哪些类型的请求会触发异常3.检测服务器响应中的异常 总结: 输入点无非就是:地址栏.和输入框 输入康输入一些非法字符,导致后台的sql语句错误,
- Laravel开发:Laravel框架门面Facade源码分析
前言 这篇文章我们开始讲 laravel 框架中的门面 Facade,什么是门面呢?官方文档: Facades(读音:/fəˈsäd/ )为应用程序的服务容器中可用的类提供了一个「静态」接口.Lara ...
- 再遇xdebug坑
xdebug.remote_handler=dbgp xdebug.idekey=PHPSTORM ;开启远程调试 xdebug.remote_enable = On ;远程主机 xdebug.rem ...
- Unity3d NGUI 360度旋转
[AddComponentMenu("NGUI/Examples/Spin With Mouse")] publicclass SpinWithMouse : MonoBehavi ...
- 自定义 ViewController 容器转场
本文转载至 http://blog.csdn.net/yongyinmg/article/details/40621463 在话题 #5 中,Chris Eidhof 向我们介绍了 iOS7 引入的新 ...
- python 补充:join() , 基本数据类型的增删改查以及深浅拷贝
# join() join() 方法用于将序列中的元素以指定的字符连接生成一个新的字符串. li = ["李李嘉诚", "麻花藤", "黄海海峰&q ...
- 解决iOS11 UIScrollView下移问题
iOS11 系统为UIScrollView增加一个contentInsetAdjustmentBehavior属性,默认为UIScrollViewContentInsetAdjustmentAutom ...