题目传送门

https://lydsy.com/JudgeOnline/problem.php?id=4898

https://loj.ac/problem/2308

题解

发现我们可以把整个环路分成很多段,每一段都携带着一个物品。

那么从 \(x\) 到 \(y\) 的这一段,我们可以预处理出应该选择什么物品。可以发现这个是不会变化的。

于是我们可以视为问题转化为了这样一个问题:给定一个有向完全图,每一条边有一个价值 \(w\),还有一个费用 \(t\),选择一个环,使得 \(\frac{\sum w}{\sum t}\) 最大。

这显然是一个分数规划的模型,于是直接二分,每条边的边权是一个 \(w-mid\cdot t\),只需要判断有没有非负的环就可以了,可以使用 \(spfa\)。


代码如下,时间复杂度为 \(nm\log W\)。

#include<bits/stdc++.h>

#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;} typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii; template<typename I> inline void read(I &x) {
int f = 0, c;
while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
x = c & 15;
while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
f ? x = -x : 0;
} const int N = 100 + 7;
const int M = 10000 + 7;
const int K = 1000 + 7;
const int INF = 0x3f3f3f3f;
const ll INF_ll = 0x3f3f3f3f3f3f3f3f; int n, m, k, maxw, hd, tl;
int b[N][K], s[N][K]; // b = buy, s = sell
int f[N][N], w[N][N];
int num[N], q[N], inq[N];
ll dis[N], g[N][N]; inline void floyd() {
for (int k = 1; k <= n; ++k)
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
if (i != j) smin(f[i][j], f[i][k] + f[k][j]);
} inline void ycl() {
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
for (int l = 1; l <= k; ++l) if (~s[j][l] && ~b[i][l]) smax(w[i][j], s[j][l] - b[i][l]);
} inline void qpush(int x) { ++tl; tl == N ? tl = 1 : 0; q[tl] = x; }
inline int qhead() { ++hd; hd == N ? hd = 1 : 0; return q[hd]; } inline bool spfa() {
hd = tl = 0;
for (int i = 1; i <= n; ++i) dis[i] = -INF_ll, inq[i] = 0, num[i] = 0;
dis[1] = 0, qpush(1), inq[1] = 1;
while (hd != tl) {
int x = qhead();
inq[x] = 0;
for (int y = 1; y <= n; ++y) if (y != x && dis[y] <= dis[x] + g[x][y]) {
dis[y] = dis[x] + g[x][y], num[y] = num[x] + 1;
if (num[y] >= n) return 1;
if (!inq[y]) qpush(y), inq[y] = 1;
}
}
return 0;
} inline bool check(const int &mid) {
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
g[i][j] = w[i][j] - (ll)mid * f[i][j];
return spfa();
} inline void work() {
floyd();
ycl();
int l = 0, r = maxw;
while (l < r) {
int mid = (l + r + 1) >> 1;
if (check(mid)) l = mid;
else r = mid - 1;
}
printf("%d\n", l);
} inline void init() {
read(n), read(m), read(k);
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= k; ++j)
read(b[i][j]), read(s[i][j]);
int x, y, z;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
if (i == j) f[i][j] = 0;
else f[i][j] = INF;
for (int i = 1; i <= m; ++i) read(x), read(y), read(z), smin(f[x][y], z), smax(maxw, z);
} int main() {
#ifdef hzhkk
freopen("hkk.in", "r", stdin);
#endif
init();
work();
fclose(stdin), fclose(stdout);
return 0;
}

bzoj4898 & loj2308 [Apio2017]商旅 最短路+01分数规划的更多相关文章

  1. 【算法】01分数规划 --- HNOI2009最小圈 & APIO2017商旅 & SDOI2017新生舞会

    01分数规划:通常的问法是:在一张有 \(n\) 个点,\(m\) 条边的有向图中,每一条边均有其价值 \(v\) 与其代价 \(w\):求在图中的一个环使得这个环上所有的路径的权值和与代价和的比率最 ...

  2. 【BZOJ4898】[Apio2017]商旅 分数规划+SPFA

    [BZOJ4898][Apio2017]商旅 Description 在广阔的澳大利亚内陆地区长途跋涉后,你孤身一人带着一个背包来到了科巴.你被这个城市发达而美丽的市场所深深吸引,决定定居于此,做一个 ...

  3. 洛谷P3778 [APIO2017]商旅——01分数规划

    题目:https://www.luogu.org/problemnew/show/P3778 转化有点技巧: 其实直接关注比率的上下两项,也就是盈利和时间: 通过暴枚和 floyd 可以处理出两两点间 ...

  4. 【learning】01分数规划

    问题描述 首先分数规划是一类决策性问题 一般形式是: \[ \lambda=\frac{f(x)}{g(x)} \] 其中\(f(x)\)和\(g(x)\)都是连续的实值函数,然后要求\(\lambd ...

  5. POJ3621Sightseeing Cows[01分数规划 spfa(dfs)负环 ]

    Sightseeing Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9703   Accepted: 3299 ...

  6. [转]01分数规划算法 ACM 二分 Dinkelbach 最优比率生成树 最优比率环

    01分数规划 前置技能 二分思想最短路算法一些数学脑细胞? 问题模型1 基本01分数规划问题 给定nn个二元组(valuei,costi)(valuei,costi),valueivaluei是选择此 ...

  7. POJ 3621 Sightseeing Cows 【01分数规划+spfa判正环】

    题目链接:http://poj.org/problem?id=3621 Sightseeing Cows Time Limit: 1000MS   Memory Limit: 65536K Total ...

  8. BZOJ2285 [SDOI2011]保密 【01分数规划 + 网络流】

    题目 现在,保密成为一个很重要也很困难的问题.如果没有做好,后果是严重的.比如,有个人没有自己去修电脑,又没有拆硬盘,后来的事大家都知道了. 当然,对保密最需求的当然是军方,其次才是像那个人.为了应付 ...

  9. 01分数规划问题(二分法与Dinkelbach算法)

    链接 前置技能 二分思想 最短路算法 一些数学脑细胞? 问题模型1基本01分数规划问题给定n个二元组(valuei,costi),valuei是选择此二元组获得的价值(非负),costi是选择此二元组 ...

随机推荐

  1. digits 2

    digits 2 震惊了== 我还交的表,发现直接输出n个n就行=== #include<bits/stdc++.h> using namespace std; ]={ ", & ...

  2. [CSP-S模拟测试]:trade(反悔贪心)

    题目传送门(内部题62) 输入格式 第一行有一个整数$n$.第二行有$N$个整数:$a_1\ a_2\ a_3\cdot\cdot\cdot a_n$. 输出格式 一行一个整数表示最大收益. 样例 样 ...

  3. ArayList的一些常用法<一> 转

    转:http://yy.azj.blog.163.com/blog/static/18508700320122893451389/ import java.util.ArrayList; import ...

  4. jQuery FileUpload doesn't trigger 'done'

     https://stackoverflow.com/questions/14674999/jquery-fileupload-doesnt-trigger-done   If your server ...

  5. python的final class

    https://zhuanlan.zhihu.com/p/31674972 https://rainmanwy.github.io/Python的final-Class/

  6. Android7.0后JNI库必须保留Section Headers

    此修改在官网的描述如下: Each ELF file has additional information contained in the section headers. These header ...

  7. 建站手册-template

    ylbtech-建站手册: 1.返回顶部   2.返回顶部   3.返回顶部   4.返回顶部   5.返回顶部     6.返回顶部   作者:ylbtech出处:http://ylbtech.cn ...

  8. Ajax对数据的删除与查看

    1.数据库找一张表: 颜色表2.主页面主页面的代码用到tbody:TBODY作用是:可以控制表格分行下载,从而提高下载速度.(网页的打开是先表格的的内容全部下载完毕后,才显示出来,分行下载可以先显示部 ...

  9. mariadb(一)基础

    一.数据库介绍 1.什么是数据库? 简单的说,数据库就是一个存放数据的仓库,这个仓库是按照一定的数据结构(数据结构是指数据的组织形式或数据之间的联系)来组织,存储的,我们可以通过数据库提供的多种方法来 ...

  10. linux下rpm包安装、配置和卸载mysq

    l   WIN10下虚拟机:VMware workstation 12 PRO 安装 # 1.查看系统版本 [root@vm-xiluhua][/home/xiluhua]$ cat /etc/red ...