题目传送门

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. 【HDOJ6645】Stay Real(堆)

    题意:给定一个n个点的堆,每个点有一个值a[i],每个点必须将在其所有儿子被取之后才能被取 有两个人都按最佳策略行动,问结束之后两人分别取的值之和 n<=1e5,1<=a[i]<=1 ...

  2. 循序渐进实现仿QQ界面(三):界面调色与控件自绘

    本篇讲述如何进行界面调色.界面调色一般有两种方法,调色板和HSL色彩变换.调色板局限于256色,这里不采用,因此用HSL色彩变换实现.首先要了解一下什么是HSL色彩空间,完整且详尽的知识请到维基百科去 ...

  3. [CSP-S模拟测试]:Median(暴力+模拟)

    题目描述 定义两个数列: $$S=\{S(1),S(2),...,S(n)\}\text{和}S_2\{S_2(1),S_2(2),...,S_2(n)\}$$ $$S(k)=(p_k\times k ...

  4. [CSP-S模拟测试]:赛(贪心+三分)

    题目描述 由于出题人思维枯竭所以想不出好玩的背景.有$n$个物品,第$i$个物品的价格是$v_i$,有两个人,每个人都喜欢$n$个物品中的一些物品.要求选出正好$m$个物品,满足选出的物品中至少有$k ...

  5. SHADER 用 step替代 if-else

    今天聊起这个问题,百度发现了这个优化方式: https://blog.csdn.net/liu_if_else/article/details/77455639

  6. RDA项目debug

  7. science_action

    w import random import pprint import math import matplotlib.pyplot as plt def gen_random(magnify_=10 ...

  8. day46----JavaScript的函数及对象小结

    一:函数 01:普通函数 function f1(){ console.log("Helleo world") } f1(); //调用函数 -->Helleo world ...

  9. 腾讯开源微服务架构 Tars,高性能 RPC 开发框架

    腾讯微服务架构 Tars 于今日正式开源. Tars 取名于电影“星际穿越”中的机器人,是支持多语言的高性能 RPC 开发框架和配套一体化的服务治理平台,可以帮助企业或者用户以微服务的方式快速构建稳定 ...

  10. 阅读笔记05-架构师必备最全SQL优化方案(1)

    一.优化的哲学 1.优化可能带来的问题? 优化不总是对一个单纯的环境进行,还很可能是一个复杂的已投产的系统: 优化手段本来就有很大的风险,只不过你没能力意识到和预见到: 任何的技术可以解决一个问题,但 ...