【洛谷 P3705】 [SDOI2017]新生舞会(费用流,01分数规划)
题目链接
看到这题我想到了以前做过的一题,名字记不清了,反正里面有“矩阵”二字,然后是道二分图匹配的题。
经典的行列连边网络流。
第\(i\)行和第\(j\)列连边,费用为\(b[i][j]-a[i][j]\times mid\),源点连行,列连汇点,跑最小费用最大流得到的最小费用取负,这个值就是最大的\(\sum a[i][j]-b[i][j]\times mid\),于是愉快的二分。
其实费用取反跑最小费用最大流再取反就是最大费用最大流。为什么不直接写最大费用最大流?我写WA了?反正就是错了。血的教训
#include <cstdio>
#include <queue>
#include <cstring>
#define INF 2147483647
using namespace std;
const int MAXN = 500;
const int MAXM = 200010;
const double eps = 1e-8;
queue <int> q;
int s, t, now, n;
struct Edge{
int from, next, to, rest;
double cost;
}e[MAXM];
int head[MAXN], num = 1, vis[MAXN], Flow[MAXN], pre[MAXN], a[110][110], b[110][110], o;
double l, r, mid, dis[MAXN];
inline void Add(int from, int to, int flow, double cost){
e[++num] = (Edge){ from, head[from], to, flow, cost }; head[from] = num;
e[++num] = (Edge){ to, head[to], from, 0, -cost }; head[to] = num;
}
int RoadsExist(){
q.push(s);
for(int i = 1; i <= o; ++i)
dis[i] = 1e10, pre[i] = 0;
dis[s] = 0; Flow[s] = INF;
while(!q.empty()){
now = q.front(); q.pop(); vis[now] = 0;
for(int i = head[now]; i; i = e[i].next)
if(e[i].rest && dis[e[i].to] > dis[now] + e[i].cost){
dis[e[i].to] = dis[now] + e[i].cost;
pre[e[i].to] = i;
Flow[e[i].to] = min(Flow[now], e[i].rest);
if(!vis[e[i].to]){
vis[e[i].to] = 1;
q.push(e[i].to);
}
}
}
return pre[t];
}
double ek(){
double maxcost = 0;
while(RoadsExist()){
maxcost += (double)Flow[t] * dis[t];
for(int i = t; i != s; i = e[pre[i]].from){
e[pre[i]].rest -= Flow[t];
e[pre[i] ^ 1].rest += Flow[t];
}
}
return -maxcost;
}
int main(){
scanf("%d", &n); o = (n << 1) + 2; s = o - 1; t = o;
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= n; ++j){
scanf("%d", &a[i][j]);
r += a[i][j];
}
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= n; ++j)
scanf("%d", &b[i][j]);
while(r - l > eps){
num = 1; mid = (l + r) / 2.0;
for(int i = 1; i <= o; ++i) head[i] = 0;
for(int i = 1; i <= n; ++i){
Add(s, i, 1, 0), Add(i + n, t, 1, 0);
for(int j = 1; j <= n; ++j)
Add(i, j + n, 1, -(double)a[i][j] + (double)b[i][j] * mid);
}
if(ek() <= 0) r = mid;
else l = mid;
}
printf("%.6lf\n", l);
return 0;
}
【洛谷 P3705】 [SDOI2017]新生舞会(费用流,01分数规划)的更多相关文章
- BZOJ 4819 [Sdoi2017]新生舞会 ——费用流 01分数规划
比值最大 分数规划 二分答案之后用费用流进行验证. 据说标称强行乘以1e7换成了整数的二分. 不过貌似实数二分也可以过. #include <map> #include <cmath ...
- 洛谷 P3705 [SDOI2017]新生舞会 解题报告
P3705 [SDOI2017]新生舞会 题目描述 学校组织了一次新生舞会,\(Cathy\)作为经验丰富的老学姐,负责为同学们安排舞伴. 有\(n\)个男生和\(n\)个女生参加舞会买一个男生和一个 ...
- 洛谷3705 [SDOI2017] 新生舞会 【01分数规划】【KM算法】
题目分析: 裸题.怀疑$ O(n^4log{n}) $跑不过,考虑Edmonds-Karp优化. 代码: #include<bits/stdc++.h> using namespace s ...
- 洛谷P2868 [USACO07DEC]观光奶牛Sightseeing Cows(01分数规划)
题意 题目链接 Sol 复习一下01分数规划 设\(a_i\)为点权,\(b_i\)为边权,我们要最大化\(\sum \frac{a_i}{b_i}\).可以二分一个答案\(k\),我们需要检查\(\ ...
- P3705 [SDOI2017]新生舞会 01分数规划+费用流
$ \color{#0066ff}{ 题目描述 }$ 学校组织了一次新生舞会,Cathy作为经验丰富的老学姐,负责为同学们安排舞伴. 有\(n\)个男生和\(n\)个女生参加舞会买一个男生和一个女生一 ...
- BZOJ 4819 Luogu P3705 [SDOI2017]新生舞会 (最大费用最大流、二分、分数规划)
现在怎么做的题都这么水了.. 题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=4819 (luogu) https://ww ...
- 【BZOJ4819】【SDOI2017】新生舞会 [费用流][分数规划]
新生舞会 Time Limit: 10 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description 学校组织了一次新生舞会,Cathy ...
- 洛谷 1004 dp或最大费用流
思路: dp方法: 设dp[i][j][k][l]为两条没有交叉的路径分别走到(i,j)和(k,l)处最大价值. 则转移方程为 dp[i][j][k][l]=max(dp[i-1][j][k-1][l ...
- 洛谷P4003 无限之环(费用流)
传送门 神仙题啊……不看题解我可能一年都不一定做得出来……FlashHu大佬太强啦 到底是得有怎样的脑回路才能一眼看去就是费用流啊…… 建好图之后套个板子就好了,那么我们着重来讨论一下怎么建图 首先, ...
- 洛谷P4012 深海机器人问题(费用流)
题目描述 深海资源考察探险队的潜艇将到达深海的海底进行科学考察. 潜艇内有多个深海机器人.潜艇到达深海海底后,深海机器人将离开潜艇向预定目标移动. 深海机器人在移动中还必须沿途采集海底生物标本.沿途生 ...
随机推荐
- 使用JsonConfig中的setExcludes方法过滤不需要转换的属性
Hibernate的many-to-one双向关联中,查询many方时会将one方数据顺带着查询,同时one中会有List<Many>,然后又会去查Many中的数据... 周而复始,结果j ...
- 详解Python闭包,装饰器及类装饰器
在项目开发中,总会遇到在原代码的基础上添加额外的功能模块,原有的代码也许是很久以前所写,为了添加新功能的代码块,您一般还得重新熟悉源代码,稍微搞清楚一点它的逻辑,这无疑是一件特别头疼的事情.今天我们介 ...
- 常用的Redis客户端的并发模型(转)
伪代码模型 # get lock : timestamp = current Unix time + lock = SETNX lock.foo timestamp or (now() > ...
- 【JQuery】使用JQuery 合并两个 json 对象
一,保存object1和2合并后产生新对象,若2中有与1相同的key,默认2将会覆盖1的值 1 var object = $.extend({}, object1, object2); 二,将2的值合 ...
- P3984 高兴的津津
题目描述 津津上高中了.她在自己的妈妈的魔鬼训练下,成为了一个神犇,每次参加一次OI比赛必拿Au虐全场.每次她拿到一个Au后就很高兴.假设津津不会因为其它事高兴,并且她的高兴会持续T天(包包含获奖当天 ...
- Check Corners HDU - 2888(二维RMQ)
就是板题.. 查询子矩阵中最大的元素...然后看看是不是四个角落的 是就是yes 不是就是no 判断一下就好了 #include <iostream> #include <cs ...
- URL补充
1. 笔记 2. 关于默认值的解释:在url里面,可以直接给views.index传递一个默认值. index函数接收一个形式参数. 在urls.py中,可以直接传递一个实参(也就是默认值). 打印结 ...
- C++11线程使用总结
std::thread 在 <thread> 头文件中声明,因此使用 std::thread 需包含 <thread> 头文件. <thread> 头文件摘要 &l ...
- 【BZOJ5319】军训列队(主席树)
[BZOJ5319]军训列队(主席树) 题面 BZOJ 洛谷 题解 一眼题既视感... 首先很明显,每次询问的结果显然是做一次离散. 然后直接上主席树就好了... 查询答案的方式也很简单 考虑一下那个 ...
- 【读书笔记】《HTTP权威指南》:Web Hosting
一.概述 从零开始构建一个真正意义的网站需要做很多事情,包括购买计算机硬件.建造机房.注册域名.购买网络带宽.开发Web服务器软件.管理网站内容等等.在互联网发展的早期,构建网站的这一系列动作通常都是 ...