【BZOJ4898】[Apio2017]商旅

Description

在广阔的澳大利亚内陆地区长途跋涉后,你孤身一人带着一个背包来到了科巴。你被这个城市发达而美丽的市场所深深吸引,决定定居于此,做一个商人。科巴有个集市,集市用从1到N的整数编号,集市之间通过M条单向道路连接,通过每条道路都需要消耗一定的时间。在科巴的集市上,有K种不同的商品,商品用从1到K的整数编号。每个集市对每种商品都有自己的定价,买入和卖出商品的价格可以是不同的。并非每个集市都可以买卖所有的商品:一个集市可能只提供部分商品的双向交易服务;对于一种商品,一个集市也可能只收购而不卖出该商品或只卖出而不收购该商品。如果一个集市收购一种商品,它收购这种商品的数量是不限的,同样,一个集市如果卖出一种商品,则它卖出这种商品的数量也是不限的。为了更快地获得收益,你决定寻找一条盈利效率最高的环路。环路是指带着空的背包从一个集市出发,沿着道路前进,经过若干个市场并最终回到出发点。在环路中,允许多次经过同一个集市或同一条道路。在经过集市时,你可以购买或者卖出商品,一旦你购买了一个商品,你需要把它装在背包里带走。由于你的背包非常小,任何时候你最多只能持有一个商品。在购买一个商品时,你不需要考虑你是否有足够的金钱,但在卖出时,需要注意只能卖出你拥有的商品。从环路中得到的收益为在环路中卖出商品得到的金钱减去购买商品花费的金钱,而一条环路上消耗的时间则是依次通过环路上所有道路所需要花费的时间的总和。环路的盈利效率是指从环路中得到的收益除以花费的时间。需要注意的是,一条没有任何交易的环路的盈利效率为0。你需要求出所有消耗时间为正数的环路中,盈利效率最高的环路的盈利效率。答案向下取整保留到整数。如果没有任何一条环路可以盈利,则输出0。

Input

第一行包含3个正整数N,M和K,分别表示集市数量、道路数量和商品种类数量。
接下来的N行,第行中包含2K个整数描述一个集市Bi,1 Si,1 Bi,2 Si,2...Bik Si,k。
对于任意的1<=j<=k,整数和分别表示在编号为的集市上购买、卖出编号为的商品时的交易价格。
如果一个交易价格为-1,则表示这个商品在这个集市上不能进行这种交易。
接下来M行,第行包含3个整数Vp,Wp和Tp,表示存在一条从编号为Vp的市场出发前往编号为Wp的市场的路径花费Tp分钟。
1<=N<=100,1<=M<=9900
如果在编号为的集市i中,编号为j的商品既可以购买又可以卖出则0<Si,j<=Bi,j<=10^9
对于编号为P(1<=P<=M)的道路,保证Vp<>Wp且1<=Tp<=10^7
不存在满足1<=P<Q<=M的P,Q,使得(Vp,Wp)=(Vq,Wq) 。

Output

输出包含一个整数,表示盈利效率最高的环路盈利效率,答案向下取整保留到整数。如果没有任何一条环路可以盈利,则输出0。
 

Sample Input

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

Sample Output

2
在样例中,我们考虑下面两条环路,“1 - 2 - 3 - 1” 和 “1 - 4 - 3 - 1”。
考虑环路 “1 - 2 - 3 - 1” :这条环路消耗的总时间是 分钟。在这条环路中,最佳的交易方式是:在编号为 1 的集市中购买编号为 2 的商品(花费的金钱为 5 );在编号为 2 的集市中卖出编号为 2 的商品(得到的金钱为 15 ),然后立即购买编号为 1 的商品(花费的金钱为 6 );带着编号为 1 的商品经过编号为 3 的集市,在回到编号为 1 的城市后卖出(得到的金钱为 9 )。在这个环路中,总盈利为13。 这个环路的盈利效率为13/7 ,向下取整后为 1 。
考虑环路 “1 - 4 - 3 - 1” :这条环路消耗的总时间是 分钟。在这条环路中,最佳的交易方式是:在编号为 1 的集市中购买编号为 2 的商品(花费的金钱为 5 );在编号为 4 的集市中卖出编号为 2 的商品(得到的金钱为 11 );然后经过编号为 3 的集市回到编号为 1 的城市。在这个环路中,总盈利为 6。 这个环路的盈利效率为6/3 ,向下取整后为 2 。
综上所述,盈利效率最高的环路的盈利效率为 2 。

题解:考场上最简单的题,嗯,当我把正解想出来时,距离考试结束还有不到20分钟~

先预处理出任意两个点之间的最短路径以及最优购买策略。那么二分答案mid,从i到j连(收益-长度*mid)的边,(如果i能到j的话),然后用SPFA判正环即可。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <queue>
  5. #include <cmath>
  6. using namespace std;
  7. typedef long long ll;
  8. int n,m,K,cnt;
  9. int S[110][1010],B[110][1010],to[20010],next[20010],head[110],inq[110],len[110];
  10. double val[20010],dis[110];
  11. int map[110][110],td[110][110];
  12. queue<int> q;
  13. inline void add(int a,int b,double c)
  14. {
  15. to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++;
  16. }
  17. bool check(double x)
  18. {
  19. int i,j,u;
  20. memset(head,-1,sizeof(head)),memset(dis,0,sizeof(dis)),cnt=0;
  21. for(i=1;i<=n;i++) for(j=1;j<=n;j++) if(i!=j&&td[i][j]>=0) add(i,j,td[i][j]-x*map[i][j]);
  22. for(i=1;i<=n;i++) q.push(i),inq[i]=len[i]=1;
  23. while(!q.empty())
  24. {
  25. u=q.front(),q.pop(),inq[u]=0;
  26. for(i=head[u];i!=-1;i=next[i]) if(dis[to[i]]<dis[u]+val[i])
  27. {
  28. dis[to[i]]=dis[u]+val[i],len[to[i]]=len[u]+1;
  29. if(len[to[i]]>n) return 1;
  30. if(!inq[to[i]]) inq[to[i]]=1,q.push(to[i]);
  31. }
  32. }
  33. return 0;
  34. }
  35. inline int rd()
  36. {
  37. int ret=0,f=1; char gc=getchar();
  38. while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
  39. while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
  40. return ret*f;
  41. }
  42. int main()
  43. {
  44. n=rd(),m=rd(),K=rd();
  45. int i,j,k,a,b,c;
  46. memset(map,0x3f,sizeof(map)),memset(td,0xc0,sizeof(td));
  47. for(i=1;i<=n;i++)
  48. {
  49. map[i][i]=0;
  50. for(j=1;j<=K;j++) B[i][j]=rd(),S[i][j]=rd();
  51. }
  52. for(i=1;i<=m;i++) a=rd(),b=rd(),c=rd(),map[a][b]=min(map[a][b],c);
  53. for(k=1;k<=n;k++) for(i=1;i<=n;i++) for(j=1;j<=n;j++) map[i][j]=min(map[i][j],map[i][k]+map[k][j]);
  54. double l=0,r=0,mid;
  55. for(i=1;i<=n;i++) for(j=1;j<=n;j++) if(i!=j&&map[i][j]<0x3f3f3f3f)
  56. {
  57. td[i][j]=0;
  58. for(k=1;k<=K;k++) if(B[i][k]!=-1&&S[j][k]!=-1&&B[i][k]<S[j][k]) td[i][j]=max(td[i][j],S[j][k]-B[i][k]);
  59. r=(r>td[i][j])?r:td[i][j];
  60. }
  61. for(i=1;i<=30;i++)
  62. {
  63. mid=(l+r)/2;
  64. if(check(mid)) l=mid;
  65. else r=mid;
  66. }
  67. printf("%d",int(floor(l+1e-9)));
  68. return 0;
  69. }

【BZOJ4898】[Apio2017]商旅 分数规划+SPFA的更多相关文章

  1. BZOJ 4898 Luogu P3778 [APIO2017]商旅 (分数规划、最短路)

    题目链接: (bzoj)https://www.lydsy.com/JudgeOnline/problem.php?id=4898 (luogu)https://www.luogu.org/probl ...

  2. 【bzoj4898】[Apio2017]商旅 Floyd+分数规划+Spfa

    题目描述 有n个点.m条边.和k种商品.第$i$个点可以以$B_{ij}$的价格买入商品$j$,并以$S_{ij}$的价格卖出.任何时候只能持有一个商品.求一个环,使得初始不携带商品时以某种交易方式走 ...

  3. 2018.09.09 poj2949Word Rings(01分数规划+spfa判环)

    传送门 这题要先巧妙的转化一下. 对于每个字符串,我们把头尾的两个小字符串对应的点连边,边权是这个字符串的长度. 这样最多会出现26*26个点. 这个时候就只用求出边权和跟边数的最大比值了. 这个显然 ...

  4. Bzoj1486/洛谷P3199 最小圈(0/1分数规划+spfa)/(动态规划+结论)

    题面 Bzoj 洛谷 题解(0/1分数规划+spfa) 考虑\(0/1\)分数规划,设当前枚举到的答案为\(ans\) 则我们要使(其中\(\forall b_i=1\)) \[ \frac{\sum ...

  5. [BZOJ4898] [Apio2017]商旅

    [BZOJ4898] [Apio2017]商旅 传送门 试题分析 考虑两个点之间的路径,显然如果交易的话肯定选\(S_{t,i}-B_{s,i}\)最大的. 那么我们可以先用\(Cost\)把两个点的 ...

  6. POJ 3621 Sightseeing Cows 【01分数规划+spfa判正环】

    题目链接:http://poj.org/problem?id=3621 Sightseeing Cows Time Limit: 1000MS   Memory Limit: 65536K Total ...

  7. 【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,然后再判 ...

  8. 【bzoj1690】[Usaco2007 Dec]奶牛的旅行 分数规划+Spfa

    题目描述 作为对奶牛们辛勤工作的回报,Farmer John决定带她们去附近的大城市玩一天.旅行的前夜,奶牛们在兴奋地讨论如何最好地享受这难得的闲暇. 很幸运地,奶牛们找到了一张详细的城市地图,上面标 ...

  9. [HNOI2009]最小圈 分数规划 spfa判负环

    [HNOI2009]最小圈 分数规划 spfa判负环 题面 思路难,代码简单. 题目求圈上最小平均值,问题可看为一个0/1规划问题,每个边有\(a[i],b[i]\)两个属性,\(a[i]=w(u,v ...

随机推荐

  1. Java8:纠结的默认方法

    [编程导论(Java)·4.3Java接口] 在[0.3.1 Java简单介绍]中,有这么一段话:"请注意:Java并不是作为教学语言设计的.世界各地的大学在讲授Java的过程中均遇到一些教 ...

  2. tomcat优化---大数据量提交tomcat时,tomcat无法接收导致页面无反应

    关于tomcat的一个优化问题: 有时候保存大数据量的数据时.tomcat不优化的话,页面会没反应.tomcat后台并不报错,仅仅是提示以下内容: 警告: More than the maximum  ...

  3. CMake 设置Target输出目录和后缀名

    一. SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/../bin) 上面的语句能设置可执行文件的输出目录 在Win + VS环境下,会自动在你所设置 ...

  4. NYOJ1097 Ugly Numbers 【丑数】

    Ugly Numbers 时间限制:1000 ms  |  内存限制:65535 KB 难度:2 描写叙述 Ugly numbers are numbers whose only prime fact ...

  5. bootstrap资料链接

    别人的博客,写的还不错 http://www.cnblogs.com/hnnydxgjj/category/879277.html

  6. Refactoring之——代码的坏味道(二)过大的类 &(三)基本类型偏执

    1.1.2 Large Class(过大的类) 特征:一个类包含过多的字段.方法.代码行. 问题原因: 类通常一开始很小,但是随着程序的增长而逐渐膨胀. 类似于过长方法,程序员通常觉得在一个现存类中添 ...

  7. 安卓开发之玩美解决ADT和SDK不一致问题

    提示:This Android SDK requires Android Developer Toolkit version 21.1.0 or above.  Current version is ...

  8. docker mongo backup 不用找啦,就在这里。

    rm -rf /tmp/mongodump && mkdir /tmp/mongodumpdocker run -it --rm --link lps-mongodb:mongo -v ...

  9. VC驿站黑客编程(关机,重新启动,注销)

    此程序在VS2013下编译通过,假设换到编译器,大家能够稍作改动使用 #include<Windows.h> #include<tchar.h> #include"r ...

  10. java 中 HashMap 遍历与删除

    HashMap的遍历 方法一.这是最常见的并且在大多数情况下也是最可取的遍历方式 /** * 在键值都需要时使用 */ Map<Integer, Integer> map = new Ha ...