https://www.luogu.org/problem/P2966

题目描述

Like everyone else, FJ is always thinking up ways to increase his revenue. To this end, he has set up a series of tolls that the cows will pay when they traverse the cowpaths throughout the farm.

The cows move from any of the N (1 <= N <= 250) pastures conveniently numbered 1..N to any other pasture over a set of M (1 <= M <= 10,000) bidirectional cowpaths that connect pairs of different pastures A_j and B_j (1 <= A_j <= N; 1 <= B_j <= N). FJ has assigned a toll L_j (1 <= L_j <= 100,000) to the path connecting pastures A_j and B_j.

While there may be multiple cowpaths connecting the same pair of pastures, a cowpath will never connect a pasture to itself. Best of all, a cow can always move from any one pasture to any other pasture by following some sequence of cowpaths.

In an act that can only be described as greedy, FJ has also assigned a toll C_i (1 <= C_i <= 100,000) to every pasture. The cost of moving from one pasture to some different pasture is the sum of the tolls for each of the cowpaths that were traversed plus a *single additional toll* that is the maximum of all the pasture tolls encountered along the way, including the initial and destination pastures.

The patient cows wish to investigate their options. They want you to write a program that accepts K (1 <= K <= 10,000) queries and outputs the minimum cost of trip specified by each query. Query i is a pair of numbers s_i and t_i (1 <= s_i <= N; 1 <= t_i <= N; s_i != t_i) specifying a starting and ending pasture.

跟所有人一样,农夫约翰以着宁教我负天下牛,休叫天下牛负我的伟大精神,日日夜夜苦思生财之道。为了发财,他设置了一系列的规章制度,使得任何一只奶牛在农场中的道路行走,都要向农夫约翰上交过路费。 农场中由N(1 <= N <= 250)片草地(标号为1到N),并且有M(1 <= M <= 10000)条双向道路连接草地A_j和B_j(1 <= A_j <= N; 1 <= B_j <= N)。

奶牛们从任意一片草地出发可以抵达任意一片的草地。FJ已经在连接A_j和B_j的双向道路上设置一个过路费L_j (1 <= L_j <= 100,000)。 可能有多条道路连接相同的两片草地,但是不存在一条道路连接一片草地和这片草地本身。最值得庆幸的是,奶牛从任意一篇草地出发,经过一系列的路径,总是可以抵达其它的任意一片草地。 除了贪得无厌,叫兽都不知道该说什么好。

FJ竟然在每片草地上面也设置了一个过路费C_i (1 <= C_i <= 100000)。从一片草地到另外一片草地的费用,是经过的所有道路的过路费之和,加上经过的所有的草地(包括起点和终点)的过路费的最大值。 任劳任怨的牛们希望去调查一下她们应该选择那一条路径。

她们要你写一个程序,接受K(1 <= K <= 10,000)个问题并且输出每个询问对应的最小花费。第i个问题包含两个数字s_i 和t_i(1 <= s_i <= N; 1 <= t_i <= N; s_i != t_i),表示起点和终点的草地。

Consider this example diagram with five pastures:

The 'edge toll' for the path from pasture 1 to pasture 2 is 3. Pasture 2's 'node toll' is 5.

To travel from pasture 1 to pasture 4, traverse pastures 1 to 3 to 5 to 4. This incurs an edge toll of 2+1+1=4 and a node toll of 4 (since pasture 5's toll is greatest), for a total cost of 4+4=8.

The best way to travel from pasture 2 to pasture 3 is to traverse pastures 2 to 5 to 3. This incurs an edge toll of 3+1=4 and a node toll of 5, for a total cost of 4+5=9.

输入格式

* Line 1: Three space separated integers: N, M, and K

* Lines 2..N+1: Line i+1 contains a single integer: C_i

* Lines N+2..N+M+1: Line j+N+1 contains three space separated

integers: A_j, B_j, and L_j

* Lines N+M+2..N+M+K+1: Line i+N+M+1 specifies query i using two space-separated integers: s_i and t_i

输出格式

* Lines 1..K: Line i contains a single integer which is the lowest cost of any route from s_i to t_i

输入输出样例

输入 #1

  1.  

输出 #1

题目大意:

给定 N 个节点,M 条边的无向图,边有边权,点有点权,现给出 Q 个询问,每个询问查询两个节点之间的最短路径,

这里最短路径的定义是两个节点之间的最短路径与这条路径中经过的节点点权的最大值之和。

题解:

多源最短路问题,数据范围这么小,很显然就应该用 floyd 算法来处理,

由于最短路径涉及到路径中最大的点权,因此如何在决策阶段快速进行状态转移,得出路径中最大的点权是这道题考虑的核心。若每次进行枚举点权,复杂度显然爆炸。

我们重新回想一遍floyd算法的原理:

i到j有两种可能:直接到和借助中间接口k,所以取一个min就行了

我们再往下细细的想一下,k代表的是中间的接口,而且k的枚举顺序是任意的?

显然是任意的!突破口就在这:我们可以肆意的修改k的枚举顺序!,所以,这道题就解决了。

我们对点按权值从小到大重新编号,这是的中转点k代表的就是重新编号的点,k越大,点权越大

我们只需要从小到大枚举中转点k,由于k是从小到大枚举的

我们在找i,j之间的最短路的时候,我们的中转点如果只是枚举到了k,这说明了我们当前的i,j之间的最短路中并没有点权超过k点点权大的点,最后的k即作为i->j的路径上除i,j外点权的最大值,

然后就可以去跑flyod,该路径上点权的最大值即为 i,j,k 三个点中点权的最大值!

因此在开始时对点权进行排序,这样对于带点权的最短路径,时间复杂度为 O(n3)。

另:单纯计算多源最短路时,各个节点之间的顺序对答案无影响。(显然如此,故可以对点重新编号)

代码如下:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <iostream>
  4. #include <string>
  5. #include <math.h>
  6. #include <algorithm>
  7. #include <vector>
  8. #include <queue>
  9. #include <set>
  10. #include <map>
  11. #include <math.h>
  12. const int INF=0x3f3f3f3f;
  13. typedef long long LL;
  14. const int mod=1e9+;
  15. const double PI=acos(-);
  16. const int maxn=;
  17. using namespace std;
  18. //ios::sync_with_stdio(false);
  19. // cin.tie(NULL);
  20.  
  21. int n,m,K;
  22. struct node
  23. {
  24. int id;//最初编号
  25. int cost;//点权
  26. }point[];//存点的信息
  27. int dis[][];//新编号的最短路径
  28. int ans[][];//带点权的最短路径(新编号),即答案
  29. int rank[];//存放新编号,由原始编号查找新编号
  30.  
  31. bool cmp(node a,node b)
  32. {
  33. return a.cost<b.cost;
  34. }
  35.  
  36. int main()
  37. {
  38. //freopen("sample.txt","r",stdin);
  39. scanf("%d %d %d",&n,&m,&K);
  40. for(int i=;i<=n;i++)
  41. {
  42. scanf("%d",&point[i].cost);
  43. point[i].id=i;
  44. }
  45. sort(point+,point++n,cmp);//按点权从小到大排序
  46. for(int i=;i<=n;i++)
  47. {
  48. rank[point[i].id]=i;//因为询问是用原始编号,这里存一下新编号
  49. }
  50. memset(dis,INF,sizeof(dis));
  51. for(int i=;i<=n;i++)
  52. {
  53. dis[i][i]=;
  54. }
  55. for(int i=;i<m;i++)
  56. {
  57. int u,v,w;
  58. scanf("%d %d %d",&u,&v,&w);
  59. dis[rank[u]][rank[v]]=dis[rank[v]][rank[u]]=min(dis[rank[u]][rank[v]],w);
  60. }
  61. memset(ans,INF,sizeof(ans));
  62. for(int k=;k<=n;k++)
  63. {
  64. for(int i=;i<=n;i++)
  65. {
  66. for(int j=;j<=n;j++)
  67. {
  68. if(i==j)
  69. continue;
  70. dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
  71. if(dis[i][j]==dis[i][k]+dis[k][j])//可去掉,但去掉运行时间会增加很多
  72. ans[i][j]=min(ans[i][j],dis[i][j]+max(point[i].cost,max(point[j].cost,point[k].cost)));
  73. }
  74. }
  75. }
  76. for(int i=;i<K;i++)
  77. {
  78. int u,v;
  79. scanf("%d %d",&u,&v);
  80. printf("%d\n",ans[rank[u]][rank[v]]);
  81. }
  82. return ;
  83. }

[USACO09DEC]牛收费路径Cow Toll Paths(floyd、加路径上最大点权值的最短路径)的更多相关文章

  1. P2966 [USACO09DEC]牛收费路径Cow Toll Paths

    P2966 [USACO09DEC]牛收费路径Cow Toll Paths 题目描述 Like everyone else, FJ is always thinking up ways to incr ...

  2. BZOJ1774[USACO 2009 Dec Gold 2.Cow Toll Paths]——floyd

    题目描述 跟所有人一样,农夫约翰以着宁教我负天下牛,休叫天下牛负我的伟大精神,日日夜夜苦思生 财之道.为了发财,他设置了一系列的规章制度,使得任何一只奶牛在农场中的道路行走,都 要向农夫约翰上交过路费 ...

  3. Luogu P2966 [USACO09DEC]牛收费路径Cow Toll Paths

    题目描述 Like everyone else, FJ is always thinking up ways to increase his revenue. To this end, he has ...

  4. 洛谷 P2966 [USACO09DEC]牛收费路径Cow Toll Paths

    题目描述 Like everyone else, FJ is always thinking up ways to increase his revenue. To this end, he has ...

  5. [USACO09DEC]牛收费路径Cow Toll Paths

    跟所有人一样,农夫约翰以着宁教我负天下牛,休叫天下牛负我的伟大精神,日日夜夜苦思生 财之道.为了发财,他设置了一系列的规章制度,使得任何一只奶牛在农场中的道路行走,都 要向农夫约翰上交过路费. 农场中 ...

  6. [Luogu P2966][BZOJ 1774][USACO09DEC]牛收费路径Cow Toll Paths

    原题全英文的,粘贴个翻译题面,经过一定的修改. 跟所有人一样,农夫约翰以宁教我负天下牛,休叫天下牛负我的伟大精神,日日夜夜苦思生财之道.为了发财,他设置了一系列的规章制度,使得任何一只奶牛在农场中的道 ...

  7. 【[USACO09DEC]牛收费路径Cow Toll Paths】

    很妙的一道题,我之前一直是用一个非常暴力的做法 就是枚举点权跑堆优化dijkstra 但是询问次数太多了 于是一直只有50分 今天终于抄做了这道题,不贴代码了,只说一下对这道题的理解 首先点权和边权不 ...

  8. 洛谷 2966 2966 [USACO09DEC]牛收费路径Cow Toll Paths

    [题意概述] 给出一个图,点有正点权,边有正边权,通过两点的代价为两点间的最短路加上路径通过的点的点权最大值. 有M个询问,每次询问通过两点的代价. [题解] 先把点按照点权从小到大排序,然后按照这个 ...

  9. P2966 [USACO09DEC]Cow Toll Paths G

    题意描述 Cow Toll Paths G 这道题翻译的是真的不错,特别是第一句话 给定一张有 \(n\) 个点 \(m\) 条边的无向图,每条边有边权,每个点有点权. 两点之间的路径长度为所有边权 ...

随机推荐

  1. 干货|浅谈iOS端短视频SDK技术实现

    短视频SDK主要包含"视频录制"和"视频编辑"这两个核心功能. 视频录制包括:视频采集.美颜.滤镜.摄像头切换.视音频采集参数设置等功能: 视频编辑包括:视频导 ...

  2. POJ - 3657 Haybale Guessing(二分+并查集)

    题意:有N个大小各不相同的点,给定Q个询问,格式为q1,q2,A,表示区间q1~q2的最小值是A,问第一个与之前询问结果出现冲突的询问. 分析: 1.二分询问的标号mid,查询1~mid是否出现询问冲 ...

  3. 图片分割之GrabCut算法、分水岭算法

    https://www.cnblogs.com/zyly/p/9392881.html 所谓图像分割指的是根据灰度.颜色.纹理和形状等特征把图像划分成若干互不交迭的区域,并使这些特征在同一区域内呈现出 ...

  4. Linux|Zookeeper--CentOS7开机启动Zookeeper

    参考 https://www.cnblogs.com/zhangmingcheng/p/7455278.html 在 /etc/rc.d/init.d 下创建zookeeper脚本 #!/bin/ba ...

  5. jdk 的安装教程

    1. 配置的位置 鼠标右击计算机----属性-----高级系统设置---环境变量----在系统变量中配置(推荐) 2.增加环境变量 (1)新建 -----  变量名:   JAVA_HOME 变量值 ...

  6. 使用Python绘制新型冠状肺炎全国增长趋势图

    截至1月28日24时,国家卫生健康委收到31个省(区.市)累计报告确诊病例5974例,现有重症病例1239例,累计死亡病例132例,累计治愈出院103例.现有疑似病例9239例.目前累计追踪到密切接触 ...

  7. LeetCode——79. 单词搜索

    给定一个二维网格和一个单词,找出该单词是否存在于网格中. 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中"相邻"单元格是那些水平相邻或垂直相邻的单元格.同一个单元格内的字 ...

  8. Java集合(一)——Collection

    集合概述 集合(Collections)是存储对象的容器.方便对多个对象的操作.存储对象,集合的作用就在这时显现了. 集合的出现就是为了持有对象.集合中可以存储任意类型的对象, 而且长度可变.在程序中 ...

  9. Dynamics CRM - 如何通过 C# Plugin 给 Contact的 主键(FullName)赋值

    Contact 是 CRM 默认带有的 Entity,主键是 <FullName>,根据开发需求,与主键相关的字段都被设置成隐藏,包括了<Full Name>,<Firs ...

  10. h5-其他伪元素

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...