Problem 2207 以撒的结合

Accept: 47    Submit: 161
Time Limit: 1000 mSec    Memory Limit : 32768 KB

 Problem Description

小茗同学最近在认真地准备比赛,所以经常玩以撒的结合。

《以撒的结合》是一款由Edmund McMillen,Florian Himsl 开发,并由Edmund McMillen最早于2011年09月29日发行的一款2D平面角色扮演、动作冒险类的独立游戏。游戏的角色将在有着能够提升能力的道具与特殊技能的半RPG世界中闯荡。

——来自百度百科

小茗同学在打BOSS前,费掉了很多HP。在地图的一些房间里有补充HP的红心,然而小茗同学受到了看不见地图的诅咒。凭借不知道哪里来的记忆,小茗同学记得某个有红心的房间在房间A与房间B的路上的第K个房间里。为了简化问题,我们把地图看成一棵树。小茗同学想知道A到B的第K个房间号为多少,由于小茗同学很累,所以现在这个任务交给你了。

 Input

第一行是一个整数T(T<=10),表示有T组测试数据。

每组数据的第一行为两个整数n m(0<n<=1000,0<m<=n*n),分别表示房间个数和询问次数。

接下来n-1行,每行两个整数u v(0<u、v<=n,且u≠v),表示地图上房间u和房间v有一条路径。

最后是m行,每行三个整数u v k,表示询问房间u到房间v的路径上的第k个房间。

输入数据保证合法,即k不超过u、v的最短距离。

 Output

对于每组数据,首先第一行先输出“Case #x:“ ,其中x是从1开始,表示数据组号,接下来m行,每行输出相应的房间号。

 Sample Input

1
6 3
1 2
2 4
2 5
1 3
3 6
4 6 4
1 6 2
4 5 3

 Sample Output

Case #1:
3
3
5

 Source

FOJ有奖月赛-2015年11月

 
 
解题思路:首先我们求出u,v两点的LCA为x,然后来判断出k在u-x段还是在v-x段。然后记录每个点u与祖先ancestor的距离,然后O(1)查询。
  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<iostream>
  4. #include<vector>
  5. #include<math.h>
  6. #include<map>
  7. #include<set>
  8. #include<queue>
  9. #include<stack>
  10. #include<string>
  11. #include<stdlib.h>
  12. #include<algorithm>
  13. using namespace std;
  14. typedef long long LL;
  15. #define mid (L+R)/2
  16. #define lson rt*2,L,mid
  17. #define rson rt*2+1,mid+1,R
  18. const int maxn = 1300;
  19. const LL mod = 1000000007;
  20. const int INF = 0x3f3f3f3f;
  21. struct AdjEdge{
  22. int to,w,next;
  23. }adjedges[maxn*2];
  24. int head[maxn];
  25. int vset[maxn*2],dep[maxn],d[maxn*2][30],first[maxn];
  26. int fa[maxn][maxn];
  27. int tot,nn;
  28. void init(){
  29. tot=0;
  30. nn=0;
  31. memset(dep,0,sizeof(dep));
  32. memset(head,-1,sizeof(head));
  33. memset(d,0,sizeof(d));
  34. memset(first,0,sizeof(first));
  35. }
  36. void addedge(int _u,int _v){ //
  37. adjedges[tot].to=_v;
  38. adjedges[tot].next=head[_u];
  39. head[_u]=tot++;
  40. // adjedges[tot].to=_u;
  41. // adjedges[tot].next=head[_v];
  42. // head[_v]=tot++;
  43. }
  44.  
  45. void dfs(int _u,int _fa,int _dep){
  46. // printf("%d %d\n",_u,_dep);
  47. dep[_u]=_dep;
  48. vset[++nn]=_u;
  49. first[_u]=nn;
  50. fa[_u][0] = _u;
  51. for(int i = 1; i <= _dep; i++){
  52. fa[_u][i] = fa[_fa][i-1];
  53. }
  54. for(int i=head[_u];i!=-1;i=adjedges[i].next){
  55. AdjEdge & e = adjedges[i];
  56. if(e.to!=_fa){
  57. dfs(e.to,_u,_dep+1);
  58. vset[++nn]=_u;
  59. }
  60. }
  61. }
  62. void ST(){
  63. for(int i=1;i<=nn;i++)
  64. d[i][0]=vset[i];
  65. for(int j=1; (1<<j)<=nn; j++){
  66. for(int i=1; i+(1<<j)-1<=nn; i++){
  67. if(dep[d[i][j-1]]<dep[d[i+(1<<(j-1))][j-1]])
  68. d[i][j]=d[i][j-1];
  69. else d[i][j]=d[i+(1 << (j-1))][j-1];
  70. }
  71. }
  72. }
  73.  
  74. int RMQ(int L,int R){
  75. int k=0;
  76. while((1<<(k+1))<=R-L+1) k++;
  77. if(dep[d[L][k]]<=dep[d[R-(1<<k)+1][k]])
  78. return d[L][k];
  79. return d[R-(1<<k)+1][k];
  80. }
  81. void tes(){
  82. for(int i =1; i <= 7; i++){
  83. for(int j = 0; j <= 4; j++){
  84. printf("%d ",fa[i][j]);
  85. }puts("");
  86. }
  87. }
  88. int main(){
  89. int T, n, q, cas = 0;
  90. scanf("%d",&T);
  91. while(T--){
  92. init();
  93. int a,b,k;
  94. scanf("%d%d",&n,&q);
  95. for(int i=1; i<n; i++){
  96. scanf("%d%d",&a,&b);
  97. addedge(a,b);
  98. addedge(b,a);
  99. }
  100. memset(fa,0,sizeof(fa));
  101. dfs(1,0,1); //dep 1
  102. ST();
  103. // tes();
  104. printf("Case #%d:\n",++cas);
  105. int x;
  106. for(int i=0; i<q; i++){
  107. scanf("%d%d%d",&a,&b,&k);
  108. if(first[a]<=first[b]){
  109. x = RMQ(first[a],first[b]);
  110. }else{
  111. x = RMQ(first[b],first[a]);
  112. }
  113. if(k == 1){
  114. printf("%d\n",a);
  115. }else if(dep[a] + dep[b] - 2*dep[x] + 1 == k){
  116. printf("%d\n",b);
  117. }else if(dep[a] - dep[x] + 1 >= k){
  118. printf("%d\n",fa[a][k-1]);
  119. }else{
  120. int kk = dep[a] + dep[b] - 2*dep[x] - k + 1;
  121. printf("%d\n",fa[b][kk]);
  122. }
  123. }
  124. }
  125. return 0;
  126. }
  127.  
  128. /*
  129. 55
  130. 7 10
  131. 1 2
  132. 1 3
  133. 2 4
  134. 2 5
  135. 5 6
  136. 5 7
  137.  
  138. 4 3 3
  139. 4 3 2
  140. 7 4 3
  141. 4 7 3
  142. 4 7 4
  143.  
  144. */

  

 
 

FZU 2207 ——以撒的结合——————【LCA + 记录祖先】的更多相关文章

  1. Uva 11354 LCA 倍增祖先

    题目链接:https://vjudge.net/contest/144221#problem/B 题意:找一条从 s 到 t  的路,使得瓶颈路最小. 点的数目是10^4,如果向之前的方案求 maxc ...

  2. FOJ 11月月赛题解

    抽空在vjudge上做了这套题.剩下FZU 2208数论题不会. FZU 2205 这是个想法题,每次可以在上一次基础上加上边数/2的新边. #include <iostream> #in ...

  3. Tarjan总结(缩点+割点(边)+双联通+LCA+相关模板)

    Tarjan求强连通分量 先来一波定义 强连通:有向图中A点可以到达B点,B点可以到达A点,则称为强连通 强连通分量:有向图的一个子图中,任意两个点可以相互到达,则称当前子图为图的强连通分量 强连通图 ...

  4. 【LCA&倍增】货物运输 @upcexam5909

    时间限制: 1 Sec 内存限制: 128 MB 题目描述 在一片苍茫的大海上,有n座岛屿,岛屿与岛屿之间由桥梁连接,所有的岛屿刚好被桥梁连接成一个树形结构,即共n-1架桥梁,且从任何一座岛屿出发都能 ...

  5. LCA离线Tarjan,树上倍增入门题

    离线Tarjian,来个JVxie大佬博客最近公共祖先LCA(Tarjan算法)的思考和算法实现,还有zhouzhendong大佬的LCA算法解析-Tarjan&倍增&RMQ(其实你们 ...

  6. lca最近公共祖先与树上倍增。

    https://vjudge.net/contest/295298#problem/A lca 的题目 求任意两点的距离. A题是在线算法,用st表rmq来实现. https://blog.csdn. ...

  7. 树链剖分 (求LCA,第K祖先,轻重链剖分、长链剖分)

      2020/4/30   15:55 树链剖分是一种十分实用的树的方法,用来处理LCA等祖先问题,以及对一棵树上的节点进行批量修改.权值和查询等有奇效. So, what is 树链剖分? 可以简单 ...

  8. P4211[BZOJ 3626] [LNOI2014]LCA

    题目描述 给出一个n个节点的有根树(编号为0到n-1,根节点为0).一个点的深度定义为这个节点到根的距离+1. 设dep[i]表示点i的深度,LCA(i,j)表示i与j的最近公共祖先. 有q次询问,每 ...

  9. HDU 5266 pog loves szh III 线段树,lca

    Pog and Szh are playing games. Firstly Pog draw a tree on the paper. Here we define 1 as the root of ...

随机推荐

  1. docker 镜像 容器删除

    Docker 容器镜像删除   1.停止所有的container,这样才能够删除其中的images: docker stop $(docker ps -a -q) 如果想要删除所有container的 ...

  2. 【题解】 UVa11292 The Dragon of Loowater

    题目大意: 你的王国里有一条n个头的恶龙,你希望雇佣一些骑士把它杀死(即砍掉所有头).村里有m个骑士可以雇佣,一个能力值为x的骑士可以砍掉恶龙一个直径不超过x的头,且需要支付x个金币.如何雇佣骑士才能 ...

  3. could not read data from '/Users/lelight/Desktop/ViewControllerLife/ViewControllerLife/Info.plist': The file “Info.plist” couldn’t be opened because there is no such file.

    1.Info.plist放置至新文件夹下,路径被修改了,报错. could not read data from '/Users/lelight/Desktop/ViewControllerLife/ ...

  4. JSON Path表达式

      JSON Path 描述 $ 表示根元素 @ 表示当前节点 .  表示子节点 .. 选择所有符合条件的节点 * 所有节点 [] 迭代器标识,如数组下标 [,] 支持迭代器中多选 [start:en ...

  5. Mysql数据库自动定时备份软件推荐--MySqlBackupFTP(免费,亲测可用,附使用图示)

    MySqlBackupFTP是一款Mysql数据库自动定时备份软件,免费版本就基本上可以满足我们的需求,不需要什么破解版,可直接官网下载安装使用. 先看结果(日志): 软件界面: 可以设定计划任务,每 ...

  6. 文件参数化-utp框架之根据yaml文件自动生成python文件+utp运行用例

    根据yaml文件自动生成python文件 utp框架: bin目录:存放执行文件(run.py) cases目录:存放生成的用例的python文件(该目录下的文件为根据data目录下的测试用例生成的p ...

  7. luoguP4213 [模板]杜教筛

    https://www.luogu.org/problemnew/show/P4213 同 bzoj3944 考虑用杜教筛求出莫比乌斯函数前缀和,第二问随便过,第一问用莫比乌斯反演来做,中间的整除分块 ...

  8. python实现对象'+'操作符

    python对象实现__add__,__radd__方法即可实现'+'操作符 demo: # coding=utf-8 class Person(object): def __init__(self, ...

  9. python之函数(二)

    上一篇中我们在函数体中的写的都是打印语句,用print来输出打印结果.但是在实际使用的时候,我们并不需要将结果输出在控制台上.这时候该如何解决呢? 1. return返回值. 我们可以将函数的结果通过 ...

  10. Visual Studio Ultimate 2013 免费下载地址

    ed2k://|file|cn_visual_studio_2010_ultimate_x86_dvd_532347.iso|2685982720|4AE6228933DDE49D9BFA4C3467 ...