题目传送门

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. ajax传递对象到MVC控制器

    1.view层中ajax写法: function Add2() { var model = new Object(); model.UserName = $('#UserName').val(); m ...

  2. layer.js插件

    官方网址: http://layer.layui.com/

  3. Shiro学习资料

    这篇博客的作者是张开涛,他写了很多专题文章,值得关注一下. 博客专栏 - 跟我学Shirohttp://www.iteye.com/blogs/subjects/shiro

  4. SpringMVC-设计模式

    MVC 设计不仅限于 Java Web 应用,还包括许多应用,比如前端.PHP..NET 等语言.之所以那么做的根本原因在于解耦各个模块. MVC 是 Model.View 和 Controller ...

  5. 文件的上传与下载实现(react、express,create-react-app脚手架)

    项目结构为前后端分离,中间布了一层node. 文件上传 要求:将文件信息等发送到后台. html代码 <input type="file" name="file&q ...

  6. drawRect

    1) 画笔设置 Paint.Style.STROKE 中空模式 paint = new Paint(); //新建一个画笔对象 paint.setAntiAlias(true);//抗锯齿功能 pai ...

  7. CET-6 分频周计划生词筛选(Week 3)

    点我阅读 Week 3 2016.09.11 p113 manipulate + propel p114 expedition + deficit p115 all p116 envisage p11 ...

  8. redis可以做什么?

    redis可以做什么? 1.缓存,毫无疑问这是Redis当今最为人熟知的使用场景.在提升服务器性能方面非常有效: 2.排行榜,如果使用传统的关系型数据库来做这个事儿,非常的麻烦,而利用Redis的So ...

  9. Django 无法通过request.POST.get()获取数据的问题

    原来是contentType为application/json时,Django不支持request.POST.get(),但可以通过request.body来获取string类型的参数: data = ...

  10. httpclient模拟服务器请求

    // 创建默认的httpClient实例. CloseableHttpClient httpclient = HttpClients.createDefault(); // 创建httppost Ht ...