【bzoj4898】[Apio2017]商旅 Floyd+分数规划+Spfa
题目描述
有n个点、m条边、和k种商品。第$i$个点可以以$B_{ij}$的价格买入商品$j$,并以$S_{ij}$的价格卖出。任何时候只能持有一个商品。求一个环,使得初始不携带商品时以某种交易方式走过一圈所得的利润/路径长度(向下取整)最大。
输入
输出
样例输入
4 5 2
10 9 5 2
6 4 20 15
9 7 10 9
-1 -1 16 11
1 2 3
2 3 3
1 4 1
4 3 1
3 1 1
样例输出
2
题解
Floyd+分数规划+Spfa
题目显然是一个分数规划的模型,但是如果直接使用分层图模拟商品买卖的过程的话肯定会TLE。
我们不妨换个思路:考虑每件两点之间的连续交易。即在A地购买商品,并在B地卖出的这个过程。
那么这个过程走的一定是最短路,买卖的一定是盈利最大的商品(当无法盈利时显然不进行买卖,盈利为0)。
所以可以使用Floyd求出任意两点之间最短路,再处理出来任意两点之间的最大盈利。
然后就可以对这个图求最大比率环了。二分答案,把每条边的权值看作 最大盈利-最短路*mid ,如果有非负环则说明mid成立,否则mid不成立。
时间复杂度$O(n^2k+n^3\log v)$。
#include <queue>
#include <cstdio>
#include <cstring>
#define N 110
#define K 1010
using namespace std;
typedef long long ll;
queue<int> q;
int n , len[N][N] , val[N][N] , b[N][K] , s[N][K] , inq[N] , num[N];
ll dis[N];
inline bool judge(int mid)
{
int x , i;
while(!q.empty()) q.pop();
for(i = 1 ; i <= n ; i ++ ) dis[i] = inq[i] = num[i] = 0 , q.push(i);
while(!q.empty())
{
x = q.front() , q.pop() , inq[x] = 0;
for(i = 1 ; i <= n ; i ++ )
{
if(dis[i] <= dis[x] + val[x][i] - (ll)mid * len[x][i])
{
dis[i] = dis[x] + val[x][i] - (ll)mid * len[x][i];
if(!inq[i])
{
if(num[i] == n) return 1;
num[i] ++ , inq[i] = 1 , q.push(i);
}
}
}
}
return 0;
}
int main()
{
int m , p , i , j , k , x , y , z , l = 1 , r = 0 , mid , ans = 0;
scanf("%d%d%d" , &n , &m , &p);
for(i = 1 ; i <= n ; i ++ )
for(j = 1 ; j <= p ; j ++ )
scanf("%d%d" , &b[i][j] , &s[i][j]);
for(i = 1 ; i <= n ; i ++ )
for(j = 1 ; j <= n ; j ++ )
for(k = 1 ; k <= p ; k ++ )
if(~b[i][k] && ~s[j][k])
val[i][j] = max(val[i][j] , s[j][k] - b[i][k]);
memset(len , 0x3f , sizeof(len));
for(i = 1 ; i <= m ; i ++ ) scanf("%d%d%d" , &x , &y , &z) , len[x][y] = z , r = max(r , z);
for(k = 1 ; k <= n ; k ++ )
for(i = 1 ; i <= n ; i ++ )
for(j = 1 ; j <= n ; j ++ )
len[i][j] = min(len[i][j] , len[i][k] + len[k][j]);
while(l <= r)
{
mid = (l + r) >> 1;
if(judge(mid)) ans = mid , l = mid + 1;
else r = mid - 1;
}
printf("%d\n" , ans);
return 0;
}
【bzoj4898】[Apio2017]商旅 Floyd+分数规划+Spfa的更多相关文章
- luogu3778/bzoj4898 商旅 (floyd+分数规划+spfa)
首先floyd求出来每两点间的最短距离,然后再求出来从某点买再到某点卖的最大收益 问题就变成了找到一个和的比值最大的环 所以做分数规划,二分出来那个答案r,把边权变成w[i]-r*l[i],再做spf ...
- 洛谷P3778 [APIO2017]商旅——01分数规划
题目:https://www.luogu.org/problemnew/show/P3778 转化有点技巧: 其实直接关注比率的上下两项,也就是盈利和时间: 通过暴枚和 floyd 可以处理出两两点间 ...
- [APIO2017]商旅(floyd+分数规划+SPFA)
题解:首先肯定要跑最短路,而n<=100,所以可以用floyd,然后根据比值,很容易想到二分答案,然后再SPFA跑一遍负环,就能求出解了. #include<bits/stdc++.h&g ...
- BZOJ4898/5367 Apio2017商旅(分数规划+floyd)
如果要在某点买入某物品并在另一点卖出,肯定是走其间最短路径.于是预处理任意两点间的收益和最短路径,连完边二分答案判负环即可,可以全程floyd.注意inf大小. #include<iostrea ...
- 2018.09.09 poj2949Word Rings(01分数规划+spfa判环)
传送门 这题要先巧妙的转化一下. 对于每个字符串,我们把头尾的两个小字符串对应的点连边,边权是这个字符串的长度. 这样最多会出现26*26个点. 这个时候就只用求出边权和跟边数的最大比值了. 这个显然 ...
- Bzoj1486/洛谷P3199 最小圈(0/1分数规划+spfa)/(动态规划+结论)
题面 Bzoj 洛谷 题解(0/1分数规划+spfa) 考虑\(0/1\)分数规划,设当前枚举到的答案为\(ans\) 则我们要使(其中\(\forall b_i=1\)) \[ \frac{\sum ...
- [BZOJ4898] [Apio2017]商旅
[BZOJ4898] [Apio2017]商旅 传送门 试题分析 考虑两个点之间的路径,显然如果交易的话肯定选\(S_{t,i}-B_{s,i}\)最大的. 那么我们可以先用\(Cost\)把两个点的 ...
- POJ 3621 Sightseeing Cows 【01分数规划+spfa判正环】
题目链接:http://poj.org/problem?id=3621 Sightseeing Cows Time Limit: 1000MS Memory Limit: 65536K Total ...
- 【bzoj1486】[HNOI2009]最小圈 分数规划+Spfa
题目描述 样例输入 4 5 1 2 5 2 3 5 3 1 5 2 4 3 4 1 3 样例输出 3.66666667 题解 分数规划+Spfa判负环 二分答案mid,并将所有边权减去mid,然后再判 ...
随机推荐
- jquery 操作css 尺寸
.height() 获取元素集合中的第一个元素的当前计算高度值,或设置每一个匹配元素的高度值. .height() 获取匹配元素集合中的第一个元素的当前计算高度值. 这个方法不接受参数. $(wind ...
- 网上商城_数据库jar包的使用
网上商城_数据库jar包的使用 0.导入数据库相关jar包 commons-dbutils-1.4.jar c3p0-0.9.1.2.jar 1.配置C3P0-config.xml文件 <?xm ...
- Uboot S3C2440 BL1 的流程
1. reset 中断向量表 2. 进入reset (1) 设置svc32 模式 (2) flash I/D caches (3)disable MMU 和 cache (4)2440 没有o ...
- float元素浮动后高度不一致导致错位的解决办方法
换行开始的第一个元素clear:left;即可 例如 四列时应该时第5个,9个...加clear:left; .row .col-lg-3:nth-child(4n+1),.row .col-md- ...
- 第1章 HTML5 概述
第 1 章 HTML5 概述 学习要点: 1.HTML5 的历史 2.HTML5 的功能 3.HTML5 的特点 4.课程学习问题 HTML5 是继 HTML4.01 和 XHTML1.0 之后的超 ...
- 【JS】window.print打印指定内容
有时候网页用到打印但是不想打印所有内容,就需要只打印指定内容,下面简单演示下如何打印指定内容 1.在需要打印的指定内容的头部前面加“<!--startprint-->”,在尾部后面加上“& ...
- python3 练习题100例 (十六)鸡尾酒疗法
#!/usr/bin/env python3 # -*- coding: utf-8 -*- __author__ = 'Fan Lijun' n = input('请输入一个大于1,小于等于20的整 ...
- 010---Django的模型层(2)
确定模型关系: ''' Publish ---- Book 多对一:一个出版社对应多本书,在多的那张表添加关联字段 Book ---- Author 多对多:一个书对应多个作者,多个作者对应一本书 会 ...
- C++机试笔记
- 12-optionBinding
1-创建一个空的dotnet mvc网站 2- 创建appsettings.json文件, 这文件会默认被绑定 { "ClassNo": "1", " ...