传送门

所以这个\(5s\)是SMG

暴力是枚举每一个点跑最短路,然后有一个很拿衣服幼稚的想法,就是把所有给出的关键点当出发点,都丢到队列里,求最短路的时候如果当前点\(x\)某个相邻的点\(y\)是关键点,就用\(dis_x+\)边权\(w_i\)更新答案.感觉这个复杂度是正确的,然后跑一下样例也对

交上去就可以获得70'的好成绩

这个方法会有一种特殊情况无法处理,就是这条路径的起点和终点都是同一点,因为图中可能有环.那么我们更新答案就不能用起点是\(y\)的路径更新答案,于是考虑同时记录从某个出发点到一个点的最短路以及是从哪个出发点转移过来的,同时求次短路,要求最短路的起点和次短路起点不一样,那么在更新答案时,如果最短路起点不等于终点就用最短路更新,否则用次短路

  1. // luogu-judger-enable-o2
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdlib>
  6. #include<cstdio>
  7. #include<vector>
  8. #include<cmath>
  9. #include<ctime>
  10. #include<queue>
  11. #include<map>
  12. #include<set>
  13. #define LL long long
  14. #define db double
  15. using namespace std;
  16. const int N=100000+10,M=500000+10;
  17. int rd()
  18. {
  19. int x=0,w=1;char ch=0;
  20. while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
  21. while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
  22. return x*w;
  23. }
  24. int to[M],nt[M],hd[N],tot;
  25. LL w[M];
  26. void add(int x,int y,int z){++tot,to[tot]=y,nt[tot]=hd[x],w[tot]=z,hd[x]=tot;}
  27. bool v[N];
  28. struct nn
  29. {
  30. LL d;
  31. int y;
  32. void clr(){d=1ll<<50,y=0;}
  33. bool operator < (const nn &bb) const {return d<bb.d;}
  34. }d1[N],d2[N];
  35. struct node
  36. {
  37. int x;
  38. nn d1,d2;
  39. bool operator < (const node &bb) const {return bb.d1.d!=d1.d?bb.d1<d1:bb.d2<d2;}
  40. };
  41. priority_queue<node> q;
  42. int n,m,kk;
  43. int main()
  44. {
  45. int T=rd();
  46. while(T--)
  47. {
  48. memset(hd,0,sizeof(hd)),tot=0;
  49. n=rd(),m=rd(),kk=rd();
  50. for(int i=1;i<=m;++i)
  51. {
  52. int x=rd(),y=rd(),z=rd();
  53. if(x==y) continue;
  54. add(x,y,z);
  55. }
  56. memset(v,0,sizeof(v));
  57. for(int i=1;i<=n;++i) d1[i].clr(),d2[i].clr();
  58. LL ans=1ll<<50;
  59. while(kk--)
  60. {
  61. int x=rd();
  62. d1[x]=(nn){0,x},v[x]=1,q.push((node){x,d1[x],d2[x]});
  63. }
  64. while(!q.empty())
  65. {
  66. int x=q.top().x;
  67. nn dd1=q.top().d1,dd2=q.top().d2;
  68. q.pop();
  69. if(d1[x]<dd1||d2[x]<dd2) continue;
  70. for(int i=hd[x];i;i=nt[i])
  71. {
  72. int y=to[i];
  73. if(v[y])
  74. {
  75. if(dd1.y!=y) ans=min(ans,dd1.d+w[i]);
  76. else ans=min(ans,dd2.d+w[i]);
  77. }
  78. else
  79. {
  80. nn n1=d1[y],n2=d2[y];
  81. if(n1.d>dd2.d+w[i])
  82. {
  83. if(n1.y!=n2.y) n2=n1;
  84. n1=(nn){dd2.d+w[i],dd2.y};
  85. }
  86. else if(n2.d>dd2.d+w[i]&&n1.y!=dd2.y) n2=(nn){dd2.d+w[i],dd2.y};
  87. if(n1.d>dd1.d+w[i])
  88. {
  89. if(n1.y!=n2.y) n2=n1;
  90. n1=(nn){dd1.d+w[i],dd1.y};
  91. }
  92. else if(n2.d>dd1.d+w[i]&&n1.y!=dd1.y) n2=(nn){dd1.d+w[i],dd1.y};
  93. if(n1<d1[y]||n2<d2[y]) q.push((node){y,d1[y]=n1,d2[y]=n2});
  94. }
  95. }
  96. }
  97. printf("%lld\n",ans);
  98. }
  99. return 0;
  100. }

luogu P5304 [GXOI/GZOI2019]旅行者的更多相关文章

  1. 【题解】Luogu P5304 [GXOI/GZOI2019]旅行者

    原题传送门 题意:给你k个点,让你求两两最短路之间的最小值 我们考虑二进制拆分,使得每两个点都有机会分在不同的组\((A:0,B:1)\)中,从源点\(S\)向\(A/B\)中的点连边权为0的边,从\ ...

  2. P5304 [GXOI/GZOI2019]旅行者

    题目地址:P5304 [GXOI/GZOI2019]旅行者 这里是官方题解 一个图 \(n\) 点 \(m\) 条边,里面有 \(k\) 个特殊点,问这 \(k\) 个点之间两两最短路的最小值是多少? ...

  3. 洛谷 P5304 [GXOI/GZOI2019]旅行者(最短路)

    洛谷:传送门 bzoj:传送门 参考资料: [1]:https://xht37.blog.luogu.org/p5304-gxoigzoi2019-lv-xing-zhe [2]:http://www ...

  4. P5304 [GXOI/GZOI2019]旅行者(最短路/乱搞)

    luogu bzoj Orz自己想出神仙正解的sxy 描述略 直接把所有起点推进去跑dijkstra... 并且染色,就是记录到这个点的最短路是由哪个起点引导出来的 然后再把所有边反指跑一次... 之 ...

  5. [洛谷P5304][GXOI/GZOI2019]旅行者

    题目大意: 有一张 \(n(n\leqslant10^5)\) 个点 \(m(m\leqslant5\times10^5)\) 条边的有向有正权图,有$k(2\leqslant k\leqslant ...

  6. [LOJ3087][GXOI/GZOI2019]旅行者——堆优化dijkstra

    题目链接: [GXOI/GZOI2019]旅行者 我们考虑每条边的贡献,对每个点求出能到达它的最近的感兴趣的城市(设为$f[i]$,最短距离设为$a[i]$)和它能到达的离它最近的感兴趣的城市(设为$ ...

  7. 【BZOJ5506】[GXOI/GZOI2019]旅行者(最短路)

    [BZOJ5506][GXOI/GZOI2019]旅行者(最短路) 题面 BZOJ 洛谷 题解 正着做一遍\(dij\)求出最短路径以及从谁转移过来的,反过来做一遍,如果两个点不由同一个点转移过来就更 ...

  8. 洛谷 P 5 3 0 4 [GXOI/GZOI2019]旅行者

    题目描述 J 国有 n 座城市,这些城市之间通过 m 条单向道路相连,已知每条道路的长度. 一次,居住在 J 国的 Rainbow 邀请 Vani 来作客.不过,作为一名资深的旅行者,Vani 只对 ...

  9. luogu P5305 [GXOI/GZOI2019]旧词

    传送门 先考虑\(k=1\),一个点的深度就是到根节点的路径上的点的个数,所以\(lca(x,y)\)的深度就是\(x\)和\(y\)到根路径的交集路径上的点的个数,那么对于一个询问,我们可以对每个点 ...

随机推荐

  1. 前端之DOM

    老师的博客:https://www.cnblogs.com/liwenzhou/p/8011504.html DOM(Document Object Model)是一套对文档的内容进行抽象和概念化的方 ...

  2. HTML基础-------HTML标签(3)

    HTML标签(3) 表格 作用:制作一个表格 属性: 标签;table>tr>td(或者th) 语义; table:一个表格 tr:一行 td:一个单元格 th:单元格的表头 captio ...

  3. mongoDB概述

    mongoDB介绍 是一个开源的文档数据库,基于分布式文件存储的数据库.由 C++ 语言编写,并领先的 NoSQL 数据库(非关系型数据库)MongoDB 是由 c++语言编写. MongoDB 是一 ...

  4. 【转】C# 定时器事件(设置时间间隔,间歇性执行某一函数,控制台程序)

    using System.Timers;定时器事件代码 static void Main(string[] args) { Method(); #region 定时器事件 Timer aTimer = ...

  5. C#使用异步操作时的注意要点(翻译)

    异步操作时应注意的要点 使用异步方法返回值应避免使用void 对于预计算或者简单计算的函数建议使用Task.FromResult代替Task.Run 避免使用Task.Run()方法执行长时间堵塞线程 ...

  6. P2801 教主的魔法(分块入门)

    两个月之前听yyr学长讲的分块,感觉是个很神奇的暴力,但到现在还是懵的一匹 #include<bits/stdc++.h> using namespace std; ; int belon ...

  7. springboot 注册dao层 service 层

    可以使用三种注解来引入DAO层的接口到spring容器中.1.@Mapper,写在每一个DAO层接口上,如下: 2.@MapperScan和@ComponentScan两者之一.前者的意义是将指定包中 ...

  8. VUE如何实现切换页面时的过渡动画?

    最近再写页面的时候,感觉页面之间的切换有点生硬,所以查了一下文档看见了transition这个组建,很实用,故此在这里跟大家分享一下 --------------------------------- ...

  9. servlet(4)异常处理

    一.异常处理 当一个 Servlet 抛出一个异常时,处理异常的servlet可以从HttpServletRequest里面得到几个属性,如下: 1.javax.servlet.error.statu ...

  10. 测试体验Centrifugo

    今天尝试用 centrifugo 来做一个在聊天室,以前用workerman做过,相对来说 workerman的配置就显得复杂多了,需要自己搭建PHP环境, 而 centrifugo 就清爽多了,官网 ...