bzoj4898 & loj2308 [Apio2017]商旅 最短路+01分数规划
题目传送门
https://lydsy.com/JudgeOnline/problem.php?id=4898
题解
发现我们可以把整个环路分成很多段,每一段都携带着一个物品。
那么从 \(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分数规划的更多相关文章
- 【算法】01分数规划 --- HNOI2009最小圈 & APIO2017商旅 & SDOI2017新生舞会
01分数规划:通常的问法是:在一张有 \(n\) 个点,\(m\) 条边的有向图中,每一条边均有其价值 \(v\) 与其代价 \(w\):求在图中的一个环使得这个环上所有的路径的权值和与代价和的比率最 ...
- 【BZOJ4898】[Apio2017]商旅 分数规划+SPFA
[BZOJ4898][Apio2017]商旅 Description 在广阔的澳大利亚内陆地区长途跋涉后,你孤身一人带着一个背包来到了科巴.你被这个城市发达而美丽的市场所深深吸引,决定定居于此,做一个 ...
- 洛谷P3778 [APIO2017]商旅——01分数规划
题目:https://www.luogu.org/problemnew/show/P3778 转化有点技巧: 其实直接关注比率的上下两项,也就是盈利和时间: 通过暴枚和 floyd 可以处理出两两点间 ...
- 【learning】01分数规划
问题描述 首先分数规划是一类决策性问题 一般形式是: \[ \lambda=\frac{f(x)}{g(x)} \] 其中\(f(x)\)和\(g(x)\)都是连续的实值函数,然后要求\(\lambd ...
- POJ3621Sightseeing Cows[01分数规划 spfa(dfs)负环 ]
Sightseeing Cows Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9703 Accepted: 3299 ...
- [转]01分数规划算法 ACM 二分 Dinkelbach 最优比率生成树 最优比率环
01分数规划 前置技能 二分思想最短路算法一些数学脑细胞? 问题模型1 基本01分数规划问题 给定nn个二元组(valuei,costi)(valuei,costi),valueivaluei是选择此 ...
- POJ 3621 Sightseeing Cows 【01分数规划+spfa判正环】
题目链接:http://poj.org/problem?id=3621 Sightseeing Cows Time Limit: 1000MS Memory Limit: 65536K Total ...
- BZOJ2285 [SDOI2011]保密 【01分数规划 + 网络流】
题目 现在,保密成为一个很重要也很困难的问题.如果没有做好,后果是严重的.比如,有个人没有自己去修电脑,又没有拆硬盘,后来的事大家都知道了. 当然,对保密最需求的当然是军方,其次才是像那个人.为了应付 ...
- 01分数规划问题(二分法与Dinkelbach算法)
链接 前置技能 二分思想 最短路算法 一些数学脑细胞? 问题模型1基本01分数规划问题给定n个二元组(valuei,costi),valuei是选择此二元组获得的价值(非负),costi是选择此二元组 ...
随机推荐
- locate 安装
locate http.conf locate apache2.conf .运行locate $ locate -bash: locate: command not found 提示找不到命令 .安装 ...
- Drawer实现侧边栏布局
在 Scaffold 组件里面传入 drawer 参数可以定义左侧边栏,传入 endDrawer 可以定义右侧边栏.侧边栏默认是隐藏的,我们可以通过手指滑动显示侧边栏,也可以通过点击按钮显示侧边栏. ...
- Prefix
Prefix 南昌邀请赛的题,字典树 #include<bits/stdc++.h> using namespace std; typedef long long ll; ll A[]; ...
- 学习日记4、datagrid多行删除
1.前台展现单选框datagrid代码 $('#List').datagrid({ url: '@Url.Action("GetList")', width: $(window). ...
- field.getModifiers() 返回值
field.getModifiers() 返回值 public static final 的值是 25 private 的值是2 测试如下 Class clazz=MyModel.class; F ...
- Windows7系统C盘空间不足
C盘要满了,用WizTree发现:;两个大文件, ①睡眠有关的,用命令提示符(管理员身份运行), 命令窗口中输入 powercfg -h off,即可关闭休眠功能,同时 Hiberfil.sys 文件 ...
- 心形陀螺案例css3
<!DOCTYPE html><html lang="zh-cn"><head> <meta charset="UTF-8&qu ...
- 1208E Let Them Slide
题目大意 给你n个序列,每个一行 每个序列是可以左右移动的 对于每一列问在随意左右移动这些序列的情况下 这一列的每个数的和最大是多少 分析 对于每个序列分为两种情况 [1]长度小于长度的一半 我们发现 ...
- P1582倒水
推了一个多小时的式子,ac后一看题解,7行代码搞定 emmmm我还是太菜了 传送 蒟蒻解法: 不管怎么倒水,最终所有瓶子里面的水的数量一定可以用2k表示出来. n最终可以合并成几个瓶子呢? 我们可以把 ...
- MATLAB 用 imresize() 函数缩小图象是 double 和 uint8 有差别
今天发现一个奇怪的现象. 在用 imresize() 缩小图象时,如果图象时 double 格式的,缩小后会产生不连通的现象. 下面是原图: 对这张图象 img 做 simg = imresize(i ...