小p和小q是好朋友,有一天小p拿到了小q的家谱,想考一下小q对家族亲属的了解程度,询问家谱中某两个人的共有的世数最大的直系先辈,小q觉得自己算这个的话很枯燥就请你帮忙写一个程序,就向你请求帮助,告诉你所有的直系血缘关系,如:“2 3”表 示为2为3的直系先辈。然后求出某两个人的共有的世数最大的直系先辈。

Input

第一行输入一个数T,表示测试样例数。对于每组测试样例,第一行输入一个数N(2<=N<=10,000)表示家谱中的人数。接下来N-1行,每行两个整数并以空格相隔,第一个整数是是第二个整数的父亲,接下来一行输入两个数,为该次询问中的两个人。

Output

对于每组测试样例,输出一个数,表示两人的共有的世数最大的直系先辈。

样例输入
2
8
1 2
1 3
1 4
2 5
3 6
3 7
7 8
6 8
5
2 1
3 5
1 3
1 4
2 5

样例输出
3
2

#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;const int MAXN = 500010;
int n, m, s, fa[MAXN], ans[MAXN],f[MAXN];
int Begin[MAXN], to[MAXN*2], Next[MAXN*2], e;
bool done[MAXN];
struct Query {int v, id;Query(int v, int id): v(v), id(id) {}
};
vector<Query> q[MAXN];inline int read() {int x = 0;char ch = getchar();while(ch < '0' || ch > '9') ch = getchar();while(ch >= '0' && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();}return x;
}inline void Add(int u, int v) {to[++e] = v;Next[e] = Begin[u];Begin[u] = e;
}int find(int x) {return fa[x] = fa[x] == x ? x : find(fa[x]);
}
int findf(int x){return x==f[x]?x:f[x]=findf(f[x]);
}
void Union(int a,int b)
{int fa=findf(a);int fb=findf(b);if(fa!=fb)f[fb]=fa;
}
void Tarjan(int u, int f) {fa[u] = u;int i;for(i = Begin[u]; i; i = Next[i]) {if(to[i] == f) continue;Tarjan(to[i], u);fa[find(to[i])] = u;}done[u] = true;for(i = 0; i < q[u].size(); i++) if(done[q[u][i].v]) ans[q[u][i].id] = find(q[u][i].v);
}int main() {int t;scanf("%d",&t);for(int k=0;k<t;k++){int i, u, v;n = read();// m = read();m=1;// s = read();for(int i=1;i<=n;i++){f[i]=i;q[i].clear();}memset(fa,0,sizeof(fa));memset(ans,0,sizeof(ans));memset(done,0,sizeof(done));memset(Begin,0,sizeof(Begin));memset(to,0,sizeof(to));memset(Next,0,sizeof(Next));for(i = 1; i < n; i++) {u = read();v = read();Add(u, v);Add(v, u);Union(u,v);}s=findf(1);//   printf("s=%d\n",s);for(i = 1; i <= m; i++) {u = read();v = read();q[u].push_back(Query(v, i));q[v].push_back(Query(u, i));}Tarjan(s, -1);for(i = 1; i <= m; i++) printf("%d\n", ans[i]);
}return 0;
}

一开始没有全部初始化,崩了几次。。。后来加了好多memset,需要自己找祖先(即根节点);

附原始tarjan模板

#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;const int MAXN = 500010;
int n, m, s, fa[MAXN], ans[MAXN];
int Begin[MAXN], to[MAXN*2], Next[MAXN*2], e;
bool done[MAXN];
struct Query {int v, id;Query(int v, int id): v(v), id(id) {}
};
vector<Query> q[MAXN];inline int read() {int x = 0;char ch = getchar();while(ch < '0' || ch > '9') ch = getchar();while(ch >= '0' && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();}return x;
}inline void Add(int u, int v) {to[++e] = v;Next[e] = Begin[u];Begin[u] = e;
}int find(int x) {return fa[x] = fa[x] == x ? x : find(fa[x]);
}void Tarjan(int u, int f) {fa[u] = u;int i;for(i = Begin[u]; i; i = Next[i]) {if(to[i] == f) continue;Tarjan(to[i], u);fa[find(to[i])] = u;}done[u] = true;for(i = 0; i < q[u].size(); i++) if(done[q[u][i].v]) ans[q[u][i].id] = find(q[u][i].v);
}int main() {int i, u, v;n = read();m = read();s = read();for(i = 1; i < n; i++) {u = read();v = read();Add(u, v);Add(v, u);}for(i = 1; i <= m; i++) {u = read();v = read();q[u].push_back(Query(v, i));q[v].push_back(Query(u, i));}Tarjan(s, -1);for(i = 1; i <= m; i++) printf("%d\n", ans[i]);return 0;
}

祖宗十九代 LCA tarjan算法相关推荐

  1. JSK习题:祖宗十九代-LCA

    思路: 经典LCA问题,且只有一次询问,可以用普通方法,即两结点向根作线,两线第一次交点即是答案 代码: #include <iostream> #include <string.h ...

  2. 空缺的2018-3-11《祖宗十九代》《缝纫机乐队》

    (1)早上7:30 起床,吃饭,然后教室复习操作系统. (2)9:30------11:30考试 (3)  吃过饭之后是12:30,百无聊赖的自己就看了电影<祖宗十九代>,以及<缝纫 ...

  3. 【数量称谓】祖宗十八代

    上序称谓 生己者为父,父之父为祖,祖父之父为曾祖,曾祖之父为高祖,高祖之父为天祖,天祖之父为烈祖,烈祖之父为太祖,太祖之父为远祖,远祖之父为鼻祖. 即:父.祖.曾.高.天.烈.太.远.鼻. 书中说:因 ...

  4. 我们常说祖宗十八代,到底是哪十八代?这个称呼又是怎么来的?

    中华文化有着非常深厚的文化底蕴,辈分也具有深刻的文化含义,古人是非常重视长幼尊卑的,几千年以来,家族文化滋养了一代一代的中国人.根深蒂固的宗族文化中,亲戚关系的成为能够条理分明地表达尊卑有序.其中,祖 ...

  5. 最近公共祖先 LCA Tarjan算法

    来自:http://www.cnblogs.com/ylfdrib/archive/2010/11/03/1867901.html 对于一棵有根树,就会有父亲结点,祖先结点,当然最近公共祖先就是这两个 ...

  6. 凸优化学习-(二十九)有约束优化算法——增广拉格朗日法、交替方向乘子法(ADMM)

    凸优化学习 我们前面说过,拉格朗日法在实际中应用不大.为什么呢?因为 α \alpha α的取值很难取,这就导致拉格朗日法鲁棒性很低,收敛很慢,解很不稳定.于是就有了今天的增广拉格朗日法和ADMM. ...

  7. 最优化学习笔记(十九)——拟牛顿法(5)BFGS算法

    一.BFGS算法的更新公式 为了推导BFGS算法,需要用到对偶或者互补的概念,前边已经讨论过hessian矩阵逆矩阵的近似矩阵需要满足以下条件: Hk+1Δg(i)=Δx(i)0≤i≤k \bolds ...

  8. 漫步最优化二十九——D.S.C.算法

    你是我的小公主,\textbf{你是我的小公主,} 像宠你宠你宠你.\textbf{像宠你宠你宠你.} 你是我的小公主,\textbf{你是我的小公主,} 我的天空是晴是雨是彩虹,\textbf{我的 ...

  9. 机器学习基础(五十九)—— 高级优化算法(梯度下降、L-BFGS、共轭梯度)

    优化算法两大核心,一曰:方向,比如由负梯度方向给出:二曰:步长. 在机器学习领域,不管是基础的梯度下降,还是更为高级的 L-BFGS.共轭梯度,都对应的是参数学习,用来学习相关模型的参数. 1. 梯度 ...

  10. R语言实战应用精讲50篇(二十九)-R语言算法应用案例:路径路网轨迹绘图分析(英国自行车数据库)

    本文主要介绍R包 PCT , 其目标是提高 Propensity to Cycle Too (PCT) 生成的数据的可访问性和可重复性,托管在 www.pct.bike 上. 英格兰和威尔士的自行车使 ...

最新文章

  1. Check failed: error == cudaSuccess (35 vs. 0) CUDA driver version is insufficient for CUDA runtime
  2. BZOJ4008. [HNOI2015]亚瑟王 期望概率dp
  3. Django和uwsgi,配合nginx做静态缓存
  4. eclipse中护眼色设置
  5. 使用spring ResponseEntity处理http响应
  6. pdol链接mysql_MySQL5.7.11免安装版的安装和配置:解决MYSQL服务无法启动问题
  7. TCP滑动窗口协议作用
  8. python的统计库_Python-Scipy库-卡方分布统计量计算
  9. saas系统用的什么语音_智能酒店语音控制系统是什么样的?
  10. C++ for循环嵌套 实现 打印10行10列星图
  11. 生物化学 电阻抗成像OpenEIT,Dbar算法,数据集等(暂记)
  12. Android手机目前常见的分辨率
  13. word如何添加页码
  14. Forge 发布倒计时三天:陈天写下他加入 ArcBlock 一周年的感慨 | ArcBlock 博客
  15. 机器学习:PR曲线及F1 score
  16. Linux安装telnet服务、telnet 命令用法
  17. Python中求最大值和最小值max()函数、min()函数
  18. Photoshop合并多个图片为PDF格式文件的(PDF文件编辑删除页面及合并的操作方法)解决方案
  19. 骨传导耳机是什么意思,骨传导耳机原理
  20. 一键启动无钥匙进入手机控车安全靠谱吗?

热门文章

  1. csu1976搬运工小明(二分)
  2. vue项目中leaflet结合天地图展示geoserver图层
  3. 人类社会发展与信息网络化
  4. 黑夜路人 PHP 简书,PHP之剑走偏锋的DeepCopy
  5. 月子会所管理系统| 月子会所小程序| 数字化门店转型
  6. 字节对齐 #pragma pack(n)
  7. 2021年电工(中级)考试报名及电工(中级)考试总结
  8. N32G430学习笔记20--- spi外设单工模式下spi1中断发送和spi2中断数据接收
  9. Gmail成功的背后故事
  10. GlobalBeacon(SM)在ICAO航空公司航班跟踪推荐惯例执行前投入使用