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 ...
随机推荐
- [分享]windows下编译squid的经验(转)
squid是什么我这里就不说了,这不是本文的重点,总之它是一个集:代理.加速.缓存.负载均衡.防盗链.访问控制等多功能的一个超牛X开源软件,如今已经广泛应用于很多领域.对于缓存和加速这一领域,如今各大 ...
- objective-C中的扩展方法与partial class
在c#中要扩展一个现有类非常easy,比方这样: ? 1 2 3 4 5 6 7 public static class Utils { public static void PrintTo ...
- jquery的on()
定义和用法 on() 方法在被选元素及子元素上添加一个或多个事件处理程序. 自 jQuery 版本 1.7 起,on() 方法是 bind().live() 和 delegate() 方法的新的替代品 ...
- Spring Boot内嵌Tomcat session超时问题
最近让Spring Boot内嵌Tomcat的session超时问题给坑了一把. 在应用中需要设置session超时时间,然后就习惯的在application.properties配置文件中设置如下, ...
- Rserve方式连接别的服务器
Rserve Rserve的方式,这是一个基于TCP/IP的服务器,通过二进制协议传输数据,可以提供远程连接,使得客户端语言能够调用R 既然是TCP/IP 就可以在不同的机器上运行了 事实上官网给出了 ...
- Android View中getViewTreeObserver().addOnGlobalLayoutListener() (转)
转自:Android View中getViewTreeObserver().addOnGlobalLayoutListener() 我们知道在oncreate中View.getWidth和View.g ...
- C语言基础知识【程序结构】
C 程序结构1.C 程序主要包括以下部分:预处理器指令函数变量语句 & 表达式注释2.#include <stdio.h> int main(){ /* 我的第一个 C 程序 ...
- [转]jquery中innerWidth(),outerWidth(),outerWidth(true)和width()的区别
转自:http://www.cnblogs.com/keyi/p/5933981.html jquery中innerWidth(),outerWidth(),outerWidth(true)和wi ...
- WINDOWS的用户和用户组说明
1.基本用户组 Administrators 属于该administators本地组内的用户,都具备系统管理员的权限,它们拥有对这台计算机最大的控制权限,可以执行整台计算机的管理任务.内置的系统管理员 ...
- PAT 1058. 选择题(20)
批改多选题是比较麻烦的事情,本题就请你写个程序帮助老师批改多选题,并且指出哪道题错的人最多. 输入格式: 输入在第一行给出两个正整数N(<=1000)和M(<=100),分别是学生人数和多 ...