Problem 2207 以撒的结合

Accept: 72    Submit: 239
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

16 31 22 42 51 33 64 6 41 6 24 5 3

Sample Output

Case #1:
3
3
5

Source

FOJ有奖月赛-2015年11月

思路:这个题目就是求最近公共祖先我用的倍增法先求出最近公共祖先(http://blog.csdn.net/lw277232240/article/details/72870644  这里有详细的讲解),然后从u点向最近公共祖先走,如果k在这里面就直接输出,如果k在另一边则从v开始向他的最近公共祖先靠拢;
代码:
#include<stdio.h>
#include<string.h>
#include<vector>
#include<stdlib.h>
#include<math.h>
#define max 40001
#define maxl 25
using namespace std;
typedef struct
{int from,to,w;
}edge;
//这个结构体用来存储边vector<edge>edges;
vector<int> G[max];//保存边的数组
int grand[max][maxl],gw[max][maxl];//x向上跳2^i次方的节点,x到他上面祖先2^i次方的距离
int depth[max];//深度
int n,m,N;
void addedge(int x,int y,int w)//把边保存起来的函数
{edge a={x,y,w},b={y,x,w};edges.push_back(a);edges.push_back(b);G[x].push_back(edges.size()-2);G[y].push_back(edges.size()-1);
}
void dfs(int x)//dfs建图
{for(int i=1;i<=N;i++)//第一个几点就全部都是0咯,第二个节点就有变化了,不理解的话建议复制代码输出下这些数组{grand[x][i]=grand[grand[x][i-1]][i-1];gw[x][i]=gw[x][i-1]+gw[grand[x][i-1]][i-1];// if(grand[x][i]==0) break;}for(int i=0;i<G[x].size();i++){   edge  e = edges[G[x][i]];if(e.to!=grand[x][0])//这里我们保存的是双向边所以与他相连的边不是他父亲就是他儿子父亲的话就不能执行,不然就{depth[e.to]=depth[x]+1;//他儿子的深度等于他爸爸的加1grand[e.to][0]=x;//与x相连那个节点的父亲等于xgw[e.to][0]=e.w;//与x相连那个节点的距离等于这条边的距离dfs(e.to);//深搜往下面建}}
}
void Init(){//n为节点个数N = floor(log(n + 0.0) / log(2.0));//最多能跳的2^i祖先depth[0]=-1;depth[1]=0;//根结点的祖先不存在,用-1表示memset(grand,0,sizeof(grand));memset(gw,0,sizeof(gw));dfs(1);//以1为根节点建树}
int lca(int a,int b)
{ if(depth[a] > depth[b]) swap(a, b);//保证a在b上面,便于计算int ans = 0;for(int i = N; i >= 0; i--) //类似于二进制拆分,从大到小尝试if(depth[a] < depth[b] && depth[grand[b][i]] >= depth[a])//a在b下面且b向上跳后不会到a上面ans +=gw[b][i], b=grand[b][i];//先把深度较大的b往上跳for(int j=N;j>=0;j--)//在同一高度了,他们一起向上跳,跳他们不相同节点,当全都跳完之后grand【a】【0】就是lca,上面有{if(grand[a][j]!=grand[b][j]){   ans+=gw[a][j];ans+=gw[b][j];a=grand[a][j];b=grand[b][j];}}if(a!=b)//a等于b的情况就是上面土色字体的那种情况{ans+=gw[a][0],ans+=gw[b][0];b=grand[b][0];}return b;
}
int main()
{ int t ;int count111;scanf("%d",&t);count111=1;while(t--){   printf("Case #%d:\n",count111++);for(int i=1;i<=n;i++){G[i].clear();}edges.clear();scanf("%d%d",&n,&m);for(int i=1;i<n;i++){int x,y,w;scanf("%d%d",&x,&y);addedge(x,y,0);}Init();int a1[1001];for(int i=1;i<=m;i++){int x,y,k;scanf("%d%d%d",&x,&y,&k);int zuxian=lca(x,y);int flag=1;//  printf("%d\n",zuxian);while(x!=zuxian){   //printf("%d\n",x);k--;if(k==0) {printf("%d\n",x);flag=0;break;}//求得祖先从x向上走;x=grand[x][0];}if(k==1) {printf("%d\n",zuxian);continue;}if(flag)//从y向上走;{ k--;int count=1;while(y!=zuxian){a1[count++]=y;y=grand[y][0];}if(count-k>=1) printf("%d\n",a1[count-k]);}}}
}

福州大学acm Problem 2207 以撒的结合相关推荐

  1. Fzu 2207 以撒的结合【思维+Dfs序】好题!好题!

     Problem 2207 以撒的结合 Accept: 68    Submit: 219 Time Limit: 1000 mSec    Memory Limit : 32768 KB  Prob ...

  2. FZU 2207 ——以撒的结合——————【LCA + 记录祖先】

    Problem 2207 以撒的结合 Accept: 47    Submit: 161 Time Limit: 1000 mSec    Memory Limit : 32768 KB  Probl ...

  3. FZU 2207 以撒的结合(LCA+记录路径)

    Problem Description 小茗同学最近在认真地准备比赛,所以经常玩以撒的结合. <以撒的结合>是一款由Edmund McMillen,Florian Himsl 开发,并由E ...

  4. Problem C 凯撒加密

    Problem Description 已知的最古老的一种加密技术是凯撒加密.该方法把一条消息中的每个字母用字母表中固定距离之后的那个字母来替代.如果越过了字母Z,会绕回到字母表的起始位置.例如,如果 ...

  5. 链接:https://ac.nowcoder.com/acm/problem/22228来源:牛客网题目描述 在给定的数组中删除一个数。输入描述:多组测试。每组第一行输入1个整数n(n

    链接:登录-专业IT笔试面试备考平台_牛客网 来源:牛客网 题目描述 在给定的数组中删除一个数. 输入描述: 多组测试. 每组第一行输入1个整数n(n<20), 第二行输入n个整数 第三行输入1 ...

  6. 牛客 /acm/problem/13223 竞标赛

    牛客NC13223: 竞标赛 题目大意为: 第一个为小美的参赛积分 对数组中 除了第一个位置以外 进行从小到大排序 然后我们通过大的与大的比较 >> 淘汰较大的 小美一直与 存活的 最小的 ...

  7. 【FOJ2207 11月月赛C】【DFS栈性质应用 离线处理】以撒的结合 从x到y路径上的第k个点 询问众多

     Problem 2207 以撒的结合 Accept: 30    Submit: 98 Time Limit: 1000 mSec    Memory Limit : 32768 KB  Probl ...

  8. fzu月赛(2015.11)

    Problem 2205 据说题目很水  Problem Description Sunday最近对图论特别感兴趣,什么欧拉回路什么哈密顿回路,又是环又是树.在看完一本书后,他对自己特别有信心,便找到 ...

  9. “玲珑杯”ACM 热身赛 # 2.5 A-B (数论)

    题目:http://www.ifrog.cc/acm/problem/1032 题意: 吐槽: 很久没写博客了~这几天准备把以前没写的题都补完. 玩了一整个寒假,都没做几道题QAQ 分析: 很久之前做 ...

最新文章

  1. 直接引用arXiv论文不规范?试试这个小工具,秒变正式发表链接,上交大校友开发...
  2. 字节跳动《算法中文手册》火了,完整版 PDF 开放下载
  3. python怎么画条形图-python绘制条形图方法代码详解
  4. 吴恩达深度学习课程deeplearning.ai课程作业:Class 2 Week 1 3.Gradient Checking
  5. 今天开始参加ORACLE PERFORMANCE TUNING 原厂培训.
  6. hdu 2072 单词数
  7. 为Envoy构建控制平面的指南-特定于域的配置API
  8. 华科02年计算机考研复试机试
  9. easypoi 导入失败返回错误文件_从Excel批量导入数据说到ForkJoin的原理
  10. Spring ScheduledTimerTask 定时任务执行
  11. 学习yii2.0框架阅读代码(九)
  12. 合并两个有序数组 Go语言
  13. 华为荣耀9手机通过在Fastboot模式写ramdisk.img来获取ROOT权限 | 华为荣耀9怎么获取ROOT权限 | 华为荣耀9怎么用面具Magisk做ROOT权限
  14. Python 刷访问量
  15. 基于机会网络环境模拟器的命名数据容迟网络的设计与实现
  16. Swift 读标准库源码笔记 -- Integers(基本数据类型篇)
  17. java系统_Java 系统
  18. 基于A*算法的迷宫游戏
  19. 大数定律与蒙特卡罗法
  20. Cadence CIS 器件管理平台解决方案

热门文章

  1. MATLAB到底有多厉害?(小白大概了解)
  2. u盘raw怎么办?数据恢复看这里!
  3. NLP常用工具及机器学习各类工具比较
  4. 企业微信群通知机器人
  5. python官网win10_win10系统python安装教程
  6. Maven搭建,配置mirror阿里云镜像,配置本地仓库
  7. linux不清楚软件包名字,技术|Shilpa Nair 分享的 RedHat Linux 包管理方面的面试经验...
  8. html列表女装分类页面,女装分类页面.html
  9. tlwar1200l设置教程_TL-WAR1200L V1.0升级软件20170609
  10. 做网页时如何使格式不随浏览器大小改变而是出现滚动条