题目传送门

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. Intel CPU编号详解

    一.概述 Intel(英特尔)是当前最主流的台式机.笔记本.服务器CPU厂商.和英特尔类似的还有AMD厂商的CPU. Intel生产的CPU型号繁多,每个型号的CPU都有对应的编号.这个编号有特定意义 ...

  2. 51nod 1514 美妙的序列 分治NTT + 容斥

    Code: #include<bits/stdc++.h> #define ll long long #define mod 998244353 #define maxn 400000 # ...

  3. 特权第一讲--Lesson 1 课程概述与如何学好FPGA

    FPGA的学习没有什么捷径,需要学习者多花时间和精力 . 1.设计输入 2.如何--对综合布局布线结果进行优化 3.如何--更有效地进行验证 4.如何--达到时序收敛 学习者需要用心去学习.去分析.去 ...

  4. 容易混淆的JavaScript基础知识之语法部分

    type 属性: 默认的 type 就是 javascript, 所以不必显式指定 type 为 javascript javascript 不强制在每个语句结尾加 “:” , javascript ...

  5. 使div弹窗可拖拽指令

    在项目开发过程中,有些情况dialog弹窗,直接使用div模拟弹窗效果,并需要支持div可拖拽. div模拟弹窗效果: (1)在用于存放指令的文件夹内,新建js文件,命名为:drag.js.具体代码如 ...

  6. tr:hover变色的问题

    做表格隔行变色(高亮显示),可以通过设置css中的 tr:hover伪类属性达到效果, 但是,会出一点小问题.td的背景色会覆盖tr的背景色, 在tr:hover下边加上一句:tr:hover td{ ...

  7. SEC6 - MySQL 查询语句--------------进阶2:条件查询

    # 进阶2:条件查询 /* 语法: select 查询列表 from 表名 where 筛选条件; 分类: 一.按照条件表达式筛选 条件运算符:> < = !=(等价于<>) ...

  8. 安全体系建设-OWASP

    OWASP Checklist Spiders, Robots and Crawlers IG- Search Engine Discovery/Reconnaissance IG- Identify ...

  9. c#Cache的用法

    public class Cache { /// <summary> /// 获取数据缓存 /// </summary> /// <param name="ca ...

  10. Requests爬取网页的编码问题

    Requests爬取网页的编码问题 import requests from requests import exceptions def getHtml(): try: r=requests.get ...