APIO2017商旅
题目大意:有$N$个点,$M$条有向边,$K$种物品,在不同的点可以用不同的价格买入或卖出某一种商品。
任意时刻至多持有一种物品,不能在同一个点先买再卖,求收益与长度之比最大的点数$\geq 2$的回路(可以不进行任何买卖)。
$N,M\leq 100,K\leq 1000,M\leq 9900$
比值最大,显然是一道分数规划的题目,难点在于建图。
如果直接在每一个点买卖分类拆点,模拟行走的过程,点数将达到$10^5$数量级,而图本身趋近于完全图,所以建图本身就会炸掉。
不难发现一个结论:从某$A$点买东西再到$B$点卖出,一定会走其最短的路径。所以,我们不妨模拟买卖的过程。
假设当前二分的比值是$x$,则点$A$到点$B$的距离就是$T(A,B)-x\times Dis(A,B)$
其中$T(A,B)=$在$K$种商品中在$A$买入在$B$卖出获得的最大利润(与$0$取最大值,因为可以不进行买卖)
$Dis(A,B)=$从$A$到$B$的最短路。
对于$T(x,y)$,直接暴力枚举每个点对和每种商品,复杂度$O(N^2K)$
对于$Dis(x,y)$,可以使用$Floyd$预处理,复杂度$O(N^3)$。
所以最终的复杂度是$O(N^2K+N^3+log(V)\cdot($求非负$($正$)$环$))$。
在求正负环时,可以采用$Bfs$和$Dfs$两种写法的$SPFA$,对于随机图,$Dfs$版本通常情况下复杂度更优,但是本题图为稠密图,而且点数较少,还是推荐使用更为稳定的$Bfs$写法的$SPFA$,复杂度下限为$O(n^3)$。
AC代码如下
- #include<algorithm>
- #include<iostream>
- #include<cstring>
- #include<cstdio>
- #include<cmath>
- #define LL long long
- #define INF 2000000000000000ll
- #define M 200020
- #define N 303
- using namespace std;
- LL read(){
- LL nm=0,fh=1;char cw=getchar();
- for(;!isdigit(cw);cw=getchar()) if(cw=='-') fh=-fh;
- for(;isdigit(cw);cw=getchar()) nm=nm*10+(cw-'0');
- return nm*fh;
- }
- LL n,m,K,G[N][N],T[N][N],B[N][1020],S[N][1020],dis[N],ind[N];
- LL fs[N],nt[M],to[M],u,v,tmp,L,R,md,ans,hd,tl,q[M];
- bool vis[N];
- void link(LL x,LL y){nt[tmp]=fs[x],fs[x]=tmp,to[tmp++]=y;}
- void init(){
- for(int i=1;i<=n;i++){
- for(int j=1;j<=n;j++){
- if(i==j) continue;
- for(int k=1;k<=K;k++){
- if(B[i][k]<0||S[j][k]<0) continue;
- T[i][j]=max(T[i][j],S[j][k]-B[i][k]);
- }
- }
- }
- for(int k=1;k<=n;k++){
- for(int i=1;i<=n;i++){
- for(int j=1;j<=n;j++) G[i][j]=min(G[i][j],G[i][k]+G[k][j]);
- }
- }
- for(int i=1;i<=n;i++){
- for(int j=1;j<=n;j++) if(i!=j&&G[i][j]<INF) link(i,j);
- }
- }
- bool check(LL now){
- for(int i=1;i<=n;i++) dis[i]=ind[i]=0;
- for(int i=1;i<=n;i++) q[tl++]=i,vis[i]=true;
- while(hd<tl){
- LL x=q[hd++]; vis[x]=false;
- for(int i=fs[x];i!=-1;i=nt[i]){
- LL len=T[x][to[i]]-now*G[x][to[i]];
- if(dis[to[i]]>dis[x]+len) continue;
- dis[to[i]]=dis[x]+len;
- if(!vis[to[i]]){
- vis[to[i]]=true,q[tl++]=to[i];
- if(++ind[to[i]]>n) return true;
- }
- }
- }
- return false;
- }
- void solve(){
- L=1ll,R=10000000000ll;
- while(L<=R){
- md=((L+R)>>1),hd=tl=0;
- if(check(md)) ans=md,L=md+1;
- else R=md-1;
- }
- }
- int main(){
- n=read(),m=read(),K=read();
- for(int i=1;i<=n;G[i][i]=0,fs[i++]=-1){
- for(int j=1;j<=n;j++) G[i][j]=INF,T[i][j]=0;
- for(int j=1;j<=K;j++) B[i][j]=read(),S[i][j]=read();
- }
- for(LL i=1;i<=m;i++) u=read(),v=read(),tmp=read(),G[u][v]=min(G[u][v],tmp);
- tmp=0,init(),solve(),printf("%lld\n",ans);
- return 0;
- }
APIO2017商旅的更多相关文章
- BZOJ 4898 [APIO2017] 商旅 | SPFA判负环 分数规划
BZOJ 4898 [APIO2017] 商旅 | SPFA判负环 分数规划 更清真的题面链接:https://files.cnblogs.com/files/winmt/merchant%28zh_ ...
- [BZOJ4898] [Apio2017]商旅
[BZOJ4898] [Apio2017]商旅 传送门 试题分析 考虑两个点之间的路径,显然如果交易的话肯定选\(S_{t,i}-B_{s,i}\)最大的. 那么我们可以先用\(Cost\)把两个点的 ...
- 【算法】01分数规划 --- HNOI2009最小圈 & APIO2017商旅 & SDOI2017新生舞会
01分数规划:通常的问法是:在一张有 \(n\) 个点,\(m\) 条边的有向图中,每一条边均有其价值 \(v\) 与其代价 \(w\):求在图中的一个环使得这个环上所有的路径的权值和与代价和的比率最 ...
- 【BZOJ4898】[Apio2017]商旅 分数规划+SPFA
[BZOJ4898][Apio2017]商旅 Description 在广阔的澳大利亚内陆地区长途跋涉后,你孤身一人带着一个背包来到了科巴.你被这个城市发达而美丽的市场所深深吸引,决定定居于此,做一个 ...
- [APIO2017]商旅——分数优化+floyd+SPFA判负环+二分答案
题目链接: [APIO2017]商旅 枚举任意两个点$(s,t)$,求出在$s$买入一个物品并在$t$卖出的最大收益. 新建一条从$s$到$t$的边,边权为最大收益,长度为原图从$s$到$t$的最短路 ...
- bzoj 4898: [Apio2017]商旅
Description 在广阔的澳大利亚内陆地区长途跋涉后,你孤身一人带着一个背包来到了科巴.你被这个城市发达而美丽的市场所 深深吸引,决定定居于此,做一个商人.科巴有个集市,集市用从1到N的整数编号 ...
- [APIO2017]商旅(floyd+分数规划+SPFA)
题解:首先肯定要跑最短路,而n<=100,所以可以用floyd,然后根据比值,很容易想到二分答案,然后再SPFA跑一遍负环,就能求出解了. #include<bits/stdc++.h&g ...
- BZOJ4898/5367 Apio2017商旅(分数规划+floyd)
如果要在某点买入某物品并在另一点卖出,肯定是走其间最短路径.于是预处理任意两点间的收益和最短路径,连完边二分答案判负环即可,可以全程floyd.注意inf大小. #include<iostrea ...
- [APIO2017]商旅 0/1分数规划
---题面--- 题解: upd: 在洛谷上被Hack了...思路应该是对的,代码就别看了 感觉有个地方还是非常妙的,就是因为在x买东西,在y卖出,就相当于直接从x走向了y,因为经过中间的城市反正也不 ...
- BZOJ4898 & BZOJ5367 & 洛谷3778:[APIO2017]商旅——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4898 https://www.lydsy.com/JudgeOnline/problem.php? ...
随机推荐
- python入门课程 第二章 安装Python
2-1 选择python版本首先python2.7和python3是不可以通用的目前丰富的类库都支持python2.7,所以选用Python2.7 选择python2.7版本2-2 window ...
- Lumen开发:简单实现auth用户认证
打开bootstrap/app.php,取消下面两段代码的注释, $app->middleware([ App\Http\Middleware\ExampleMiddleware::class ...
- EhCache 集群 配置(RMI方式)
这里先说明下环境:JDK1.6.ehcache-core-2.1.0.jar.Tomcat6.Spring3.0.2.使用的是RMI方式配置集群的,这里先吐槽下遇到的情况,在搜相关知识的时候发现到处都 ...
- CAFFE学习笔记(一)Caffe_Example之训练mnist
0.参考文献 [1]caffe官网<Training LeNet on MNIST with Caffe>; [2]薛开宇<读书笔记4学习搭建自己的网络MNIST在caffe上进行训 ...
- elasticsearch从入门到出门-05-集群之踩坑
自己搭的集群, 设备: win10 + ubuntu 16 的虚拟机一个: 下载的版本:elasticsearch-5.2.0 win10 解压下就好了,不说了. ubuntu 上,我想说多了都是泪! ...
- Java基础 - 变量的定义和使用
变量定义 public class Main { public static void main(String[] args) { // 定义byte类型的变量 byte b = 10; System ...
- Android笔记之GridView
完整Demo链接:https://pan.baidu.com/s/1d_G9aCwBxpiYQcdQhwSDDw,提取码:5deh 效果图 activity_main.xml <?xml ver ...
- PAT 1065. 单身狗(25)
“单身狗”是中文对于单身人士的一种爱称.本题请你从上万人的大型派对中找出落单的客人,以便给予特殊关爱. 输入格式: 输入第一行给出一个正整数N(<=50000),是已知夫妻/伴侣的对数:随后N行 ...
- Python读属性文件
# coding:utf-8 class Properties: def __init__(self, file_name): self.file_name = file_name self.prop ...
- Spring 拦截器——HandlerInterceptor
采用Spring拦截器的方式进行业务处理.HandlerInterceptor拦截器常见的用途有: 1.日志记录:记录请求信息的日志,以便进行信息监控.信息统计.计算PV(Page View)等. 2 ...