这个题目大意是:

    有N个城市,编号为0~N-1,给定N-1条无向带权边,Q个询问,每个询问求三个城市连起来的最小权值。

    多组数据 每组数据  1 < N < 50000  1 < Q < 70000;

    一道多源最短路的题目,注意题目数据:N、Q都很大

    不能考虑Floyd、SPFA、Dijkstra、Bellman-Ford等最短路算法

    再看N-1条边,明显构成一棵树,最短路有且只有一条

    很明显需要LCA....

    不懂LCA的点!我!点!我

    我们所熟知的LCA是求两个点的最短路,而该题稍微变形,要求三个点

    所以我们可以两两求LCA,然后把三个dist值加起来除以二

    而两点的dist值是这样算的:dist[a]+dist[b]-2*dist[LCA(a,b)]

    代码如下:

    

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <algorithm>
  5. #define N 200010
  6. #define M 600010
  7. using namespace std;
  8. struct DATA
  9. {
  10. int from,to,dis,next,i;
  11. }road[N],ques[M];
  12. int dist[N],head1[N],head2[M],f[N],ans[M],n,q,len1,len2,fun=;
  13. bool vis[N],book[M],found[N];
  14. void add1(int a,int b,int c,int i)
  15. {
  16. len1++;
  17. road[len1].from=a;
  18. road[len1].to=b;
  19. road[len1].dis=c;
  20. road[len1].i=i;
  21. road[len1].next=head1[a];
  22. head1[a]=len1;
  23. }
  24. void add2(int a,int b,int c,int i)
  25. {
  26. len2++;
  27. ques[len2].from=a;
  28. ques[len2].to=b;
  29. ques[len2].dis=c;
  30. ques[len2].i=i;
  31. ques[len2].next=head2[a];
  32. head2[a]=len2;
  33. }
  34. int find(int x){return f[x]==x?x:f[x]=find(f[x]);}
  35. void marge(int x,int y){if(find(x)!=find(y)) f[y]=x;}
  36. void Tarjan(int u,int dev)
  37. {
  38. int e=head1[u],a,b,i,tmp;
  39. while(e!=-)
  40. {
  41. a=road[e].to;
  42. i=road[e].i;
  43. tmp=dev+road[e].dis;
  44. if(!vis[a] && !found[i])
  45. {
  46. found[i]=;
  47. dist[a]=tmp;
  48. Tarjan(a,tmp);
  49. vis[a]=;
  50. marge(u,a);
  51. }
  52. e=road[e].next;
  53. }
  54. e=head2[u];
  55. while(e!=-)
  56. {
  57. a=ques[e].to;
  58. i=ques[e].i;
  59. if(vis[a] && !book[i])
  60. {
  61. book[i]=;
  62. b=find(a);
  63. ans[i]=dist[a]+dist[u]-*dist[b];
  64. }
  65. e=ques[e].next;
  66. }
  67. return ;
  68. }
  69. void init()
  70. {
  71. int i;
  72. len1=,len2=;
  73. for(i=;i<N;i++)
  74. {
  75. road[i].from=road[i].to=road[i].dis=road[i].next=road[i].i=;
  76. f[i]=i;
  77. }
  78. for(i=;i<M;i++)
  79. ques[i].from=ques[i].to=ques[i].dis=ques[i].next=ques[i].i=;
  80. memset(head1,-,sizeof(head1));
  81. memset(head2,-,sizeof(head2));
  82. memset(dist,,sizeof(dist));
  83. memset(vis,,sizeof(vis));
  84. memset(book,,sizeof(book));
  85. memset(found,,sizeof(found));
  86. memset(ans,,sizeof(ans));
  87. return ;
  88. }
  89. int main()
  90. {
  91. // freopen("1.in","r",stdin);
  92. // freopen("test.out","w",stdout);
  93. while(~scanf("%d",&n))
  94. {
  95. if(fun++) printf("\n");
  96. init();
  97. int i,a,b,c,tmp=;
  98. for(i=;i<n;i++)
  99. {
  100. scanf("%d%d%d",&a,&b,&c);
  101. add1(a,b,c,i);
  102. add1(b,a,c,i);
  103. tmp=min(min(a,b),tmp);
  104. }
  105. scanf("%d",&q);
  106. for(i=;i<=q;i++)
  107. {
  108. scanf("%d%d%d",&a,&b,&c);
  109. add2(a,b,,i);
  110. add2(b,a,,i);
  111. add2(a,c,,i+q);
  112. add2(c,a,,i+q);
  113. add2(b,c,,i+*q);
  114. add2(c,b,,i+*q);
  115. }
  116. Tarjan(tmp,);
  117. for(i=;i<=q;i++)
  118. printf("%d\n",(ans[i]+ans[i+q]+ans[i+*q])/);
  119. }
  120. return ;
  121. }

ZOJ 3195 Design the city 题解的更多相关文章

  1. zoj——3195 Design the city

    Design the city Time Limit: 1 Second      Memory Limit: 32768 KB Cerror is the mayor of city HangZho ...

  2. ZOJ 3195 Design the city (LCA 模板题)

    Cerror is the mayor of city HangZhou. As you may know, the traffic system of this city is so terribl ...

  3. zoj 3195 Design the city LCA Tarjan

    题目链接 : ZOJ Problem Set - 3195 题目大意: 求三点之间的最短距离 思路: 有了两点之间的最短距离求法,不难得出: 对于三个点我们两两之间求最短距离 得到 d1 d2 d3 ...

  4. ZOJ 3195 Design the city LCA转RMQ

    题意:给定n个点,下面n-1行 u , v ,dis 表示一条无向边和边权值,这里给了一颗无向树 下面m表示m个询问,问 u v n 三点最短距离 典型的LCA转RMQ #include<std ...

  5. ZOJ - 3195 Design the city

    题目要对每次询问将一个树形图的三个点连接,输出最短距离. 利用tarjan离线算法,算出每次询问的任意两个点的最短公共祖先,并在dfs过程中求出离根的距离.把每次询问的三个点两两求出最短距离,这样最终 ...

  6. zoj 3195 Design the city lca倍增

    题目链接 给一棵树, m个询问, 每个询问给出3个点, 求这三个点之间的最短距离. 其实就是两两之间的最短距离加起来除2. 倍增的lca模板 #include <iostream> #in ...

  7. ZOJ Design the city LCA转RMQ

    Design the city Time Limit: 1 Second      Memory Limit: 32768 KB Cerror is the mayor of city HangZho ...

  8. ZOJ3195 Design the city [2017年6月计划 树上问题04]

    Design the city Time Limit: 1 Second      Memory Limit: 32768 KB Cerror is the mayor of city HangZho ...

  9. xtu summer individual 1 C - Design the city

    C - Design the city Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu D ...

随机推荐

  1. windows 安装 Scrapy的套路

    我最近在琢磨scrapy爬虫框架,在windows中安装scrapy遇到了不少坑:直接 pip install scrapy 安装不成功的,百度说要安装vc2008+等等,安装这些时间太长,最后找到一 ...

  2. iOS性能检测之Instrunments - 几种常用工具简单介绍

    Instrunments:  没错,就是这货,很多人平时开发可能不一定会用到这个,但我要说的是,学会使用它,会让你加分不少哦 先来一张全家福: 1.打开方式 或者 两种方式都行. 2.今天主要介绍一下 ...

  3. jquery 中时间的运用

    运用Moment插件比较方面,有兴趣可以仔细阅读 http://momentjs.cn/

  4. YARN学习笔记(一)——YARN的简介

    YARN的简介 什么是YARN MRv1的架构和缺陷 经典MapReduce的局限性 解决可伸缩性问题 YARN的架构 一个可运行任何分布式应用程序的集群 YARN中的应用程序提交 YARN的其他特性 ...

  5. iOS 调试心得

    修复 bug 占用我们日常开发的大部分时间,熟练的使用调试工具可以给我们节约大部分的时间. LLDB 的常用命令 expression expresion 是一个非常常用的命令,我们可以通过这个命令来 ...

  6. Gradle之恋-任务2

    由于任务作为Gradle的核心功能模块,多花点精力是值得的,本文继上一篇主要涉及到:任务的执行顺序.为任务添加组和描述.跳过任务.扩展任务属性.定义默认任务. 任务顺序 如果构建(build)不能在清 ...

  7. ios8指纹识别

    简介 苹果从iPhone5S开始,具有指纹识别技术,从iOS8.0之后苹果允许第三方 App 使用 Touch ID进行身份验证.指纹识别Touch ID提供3+2共5次指纹识别机会(3次识别失败后, ...

  8. servlet匹配规则和顺序

    1.  写法 ①完全匹配:以“/”开头,以字母(非“*”)结束    如:<url-pattern>/test/list.do</url-pattern> ②目录匹配:以“/” ...

  9. freemodbus移植讲解 ZZ

    一   为什么要移植Freemodbus 为什么要移植Freemodbus,这个问题需要从两个方面来回答.第一,modbus是一个非常好的应用层协议,它很简洁也相对完善.对于还没有接触过modbus的 ...

  10. 图解Javascript——变量对象和活动对象

    span { line-height: 1.5 } 这是由一段代码引发的思考: var laterDeclaredVar = 'I am a global variable ...'; (functi ...