【题意】给你N个点,N条不同的边,Q次询问,求出u,v之间的最短路。

【分析】题意很简单,就是求最短路,但是Q次啊,暴力DIJ?当然不行,观察到这个题边的数目和点的数目是相同的,也就是说这个图是由一棵树加了一条边而形成的。而对于一棵树,如果有Q次询问最短路,那就可以用LCA来做,复杂度QlogN,但是现在加了一条边,可能会使有些点之间的路径变短。假设多加的这条边的两个端点是U,V,那么对于询问的X,Y,有这么三种情况,直接过LCA,或者经过U,V,详情见代码。

  1. #include <bits/stdc++.h>
  2. #define met(a,b) memset(a,b,sizeof a)
  3. #define pb push_back
  4. #define mp make_pair
  5. #define lson l,m,rt<<1
  6. #define rson m+1,r,rt<<1|1
  7. #define lowbit(x) (x&(-x))
  8. using namespace std;
  9. typedef long long ll;
  10. ll mod = 1e9+;
  11. const int N=3e4+;
  12. const int M=N*N+;
  13. int n,m,k,root,son,dis[N],dep[N],fa[N][],parent[N];
  14. int d;
  15. vector<pair<int,int> >edg[N];
  16. int Find(int x){
  17. if(parent[x]!=x)parent[x]=Find(parent[x]);
  18. return parent[x];
  19. }
  20. void Union(int x,int y){
  21. x=Find(x);
  22. y=Find(y);
  23. if(x==y)return;
  24. parent[y]=x;
  25. }
  26. void dfs(int u,int f){
  27. fa[u][]=f;
  28. for(int i=; i<; i++){
  29. fa[u][i]=fa[fa[u][i-]][i-];
  30. }
  31. for(int i=; i<edg[u].size(); i++){
  32. int v=edg[u][i].first;
  33. if(v==f)continue;
  34. dis[v]=dis[u]+edg[u][i].second;
  35. dep[v]=dep[u]+;
  36. dfs(v,u);
  37. }
  38. }
  39. int Lca(int u,int v){
  40. int U=u,V=v;
  41. if(dep[u]<dep[v])swap(u,v);
  42. for(int i=; i>=; i--){
  43. if(dep[fa[u][i]]>=dep[v]){
  44. u=fa[u][i];
  45. }
  46. }
  47. if(u==v)return u;
  48. for(int i=; i>=; i--){
  49. if(fa[u][i]!=fa[v][i]){
  50. u=fa[u][i];
  51. v=fa[v][i];
  52. }
  53. }
  54. return fa[u][];
  55. }
  56. int main(){
  57. int u,v,w;
  58. int T;
  59. scanf("%d",&T);
  60. while(T--){
  61. for(int i=; i<N; i++)dis[i]=dep[i]=,edg[i].clear(),parent[i]=i;
  62. met(fa,-);
  63. scanf("%d%d",&n,&m);
  64. for(int i=; i<=n; i++){
  65. scanf("%d%d%d",&u,&v,&w);
  66. u++;v++;
  67. if(Find(u)==Find(v))root=u,son=v,d=w;
  68. else{
  69. Union(u,v);
  70. edg[u].pb(mp(v,w));
  71. edg[v].pb(mp(u,w));
  72. }
  73. }
  74. dep[root]=;
  75. dfs(root,-);
  76. while(m--){
  77. scanf("%d%d",&u,&v);
  78. u++;v++;
  79. int lca=Lca(u,v);
  80. int ans1=dis[u]+dis[v]-*dis[lca];
  81. int ans2=dis[u]+dis[son]-*dis[Lca(u,son)]+dis[v]+dis[root]-*dis[Lca(root,v)]+d;
  82. int ans3=dis[v]+dis[son]-*dis[Lca(v,son)]+dis[u]+dis[root]-*dis[Lca(root,u)]+d;
  83. printf("%d\n",min(ans1,min(ans2,ans3)));
  84. }
  85. }
  86. return ;
  87. }

北方大学 ACM 多校训练赛 第七场 C Castle(LCA)的更多相关文章

  1. 2018牛客网暑假ACM多校训练赛(第二场)E tree 动态规划

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round2-E.html 题目传送门 - 2018牛客多校赛第二场 E ...

  2. HDU 4941 Magical Forest(map映射+二分查找)杭电多校训练赛第七场1007

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4941 解题报告:给你一个n*m的矩阵,矩阵的一些方格中有水果,每个水果有一个能量值,现在有三种操作,第 ...

  3. 2018牛客网暑假ACM多校训练赛(第三场)I Expected Size of Random Convex Hull 计算几何,凸包,其他

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round3-I.html 题目传送门 - 2018牛客多校赛第三场 I ...

  4. 2018牛客网暑假ACM多校训练赛(第三场)G Coloring Tree 计数,bfs

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round3-G.html 题目传送门 - 2018牛客多校赛第三场 G ...

  5. 2018牛客网暑假ACM多校训练赛(第三场)D Encrypted String Matching 多项式 FFT

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round3-D.html 题目传送门 - 2018牛客多校赛第三场 D ...

  6. 2018牛客网暑假ACM多校训练赛(第十场)H Rikka with Ants 类欧几里德算法

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round10-H.html 题目传送门 - https://www.n ...

  7. 2018牛客网暑假ACM多校训练赛(第十场)F Rikka with Line Graph 最短路 Floyd

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round10-F.html 题目传送门 - https://www.n ...

  8. 2018牛客网暑假ACM多校训练赛(第十场)D Rikka with Prefix Sum 组合数学

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round10-D.html 题目传送门 - https://www.n ...

  9. 2018牛客网暑假ACM多校训练赛(第八场)H Playing games 博弈 FWT

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round8-H.html 题目传送门 - https://www.no ...

随机推荐

  1. LightOJ 1306 - Solutions to an Equation 裸EXGCD

    本题是极其裸的EXGCD AX+BY+C=0 给你a b c 和x与y的区间范围,问你整数解有几组 作为EXGCD入门,题目比较简单 主要需要考虑区间范围的向上.向下取整,及正负符号的问题 问题是这正 ...

  2. 【NOIP】提高组2012 疫情控制

    [题意]n个点的树,1为根,要求删除一些点使得截断根节点和所有叶子结点的路径(不能删根,可以删叶子).有m支军队在m个点上,每时刻所有军队可以走一步,最终走到的地方就是删除的点,求最短时间. [算法] ...

  3. 【洛谷 P2513】 [HAOI2009]逆序对数列(DP)

    题目链接 这种求方案数的题一般都是\(dp\)吧. 注意到范围里\(k\)和\(n\)的范围一样大,\(k\)是完全可以更大的,到\(n\)的平方级别,所以这暗示了我们要把\(k\)写到状态里. \( ...

  4. 完全教程 Aircrack-ng破解WEP、WPA-PSK加密利器

    其 实关于无线基础知识的内容还是挺多的,但是由于本书侧重于BT4自身工具使用的讲解,若是再仔细讲述这些外围的知识,这就好比讲述DNS工具时还要把 DNS服务器的类型.工作原理及配置讲述一遍一样,哈哈, ...

  5. php中的__call()函数重载

    <?php #调用类中没有的方法时, 会自动调用__call方法重载 #第一个参数是调用时的方法名, 第二个参数为参数组成的数组 class Cat{ public function Hello ...

  6. 【Python学习笔记】Coursera课程《Using Python to Access Web Data》 密歇根大学 Charles Severance——Week6 JSON and the REST Architecture课堂笔记

    Coursera课程<Using Python to Access Web Data> 密歇根大学 Week6 JSON and the REST Architecture 13.5 Ja ...

  7. sql 自定义split

    以下数据库操作针对sql server. 问题来源:由于项目中,有的表字段内容是由多个id或多个其他内容拼接而成.(如:'1,2,3,4,5',或者'name_age_school'),特点是都用某个 ...

  8. Linux内核的架构

    GNU/Linux操作系统架构 备注:IPC进程间通.IPC(Inter-Process Communication)是共享"命名管道"的资源,它是为了让进程间通信而开放的命名管道 ...

  9. monkey测试===如何获取android app的Activity

    方法一(推荐): 手机连接adb,手机界面在需要取得activity的界面. 推荐使用该命令: adb shell dumpsys activity top | findstr ACTIVITY 获取 ...

  10. 【bzoj1649】Cow Roller Coaster

    傻逼dp题. dp[i][j]表示用了i长度已花费成本j所能得到的价值. 然后枚举一下铁轨随便做了. 不行就sort一下. #include<bits/stdc++.h> #define ...