package LCA;import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Scanner;/*** @Author: * @Date : 2020/8/20 8:44* Tarjan算法基于深度优先搜索的框架,对于新搜索到的一个结点,首先创建由这个结点构成的集合,再对当前结点的每一个子树进行搜索,* 每搜索完一棵子树,则可确定子树内的LCA询问都已解决。其他的LCA询问的结果必然在这个子树之外,* 这时把子树所形成的集合与当前结点的集合合并,并将当前结点设为这个集合的祖先。之后继续搜索下一棵子树,* 直到当前结点的所有子树搜索完。这时把当前结点也设为已被检查过的,同时可以处理有关当前结点的LCA询问,* 如果有一个从当前结点到结点v的询问,且v已被检查过,则由于进行的是深度优先搜索,当前结点与v的最近公共祖先一定还没有被检查,* 而这个最近公共祖先的包涵v的子树一定已经搜索过了,那么这个最近公共祖先一定是v所在集合的祖先。**/
public class POJ1330_20200820 {// 并查集部分// 父节点static int[] p;//并查集是一种数据结构:某个元素是否属于某个集合,或者 某个元素 和 另一个元素是否同属于一个集合static int find(int u){if(p[u]!=u){p[u] = find(p[u]);}return p[u];}static class Edge{int to;//这条边到达的点.int next;//表示与第i条边同起点的的下一条边的存储位置.}// 链式前向星static int[] head;  //数组head[],它是用来表示以i为起点的第一条边存储的位置,实际上你会发现这里的第一条边存储的位置其实。// 在以i为起点的所有边的最后输入的那个编号.static Edge[] edges;static boolean[] vist;// 所求LCA的两点static int qfrom;static int qto;// 找根static boolean[] isroot;static boolean LCA(int u){// 在以自己为根的子树中计算LCA// 如果没找到就回溯到父节点,再向下去兄弟子树计算// 先建立以自己为代表的并查集p[u]=u;//作为当前的根节点,将其父亲指向自己vist[u]=true;//标记该点已经走过for(int k=head[u];k>=0;k=edges[k].next){//查找子节点int to = edges[k].to;if(!vist[to]) {// 计算子树// 如果在某棵子树计算过程中算出结果,就返回trueif(LCA(to))return true;// 子树计算完,把子树的并查集代表节点设为当前节点p[to] = u;}}// 所有子树计算完毕,还没发现结果// 试试用当前节点计算结果if(u == qfrom){if(vist[qto]){System.out.println(find(qto));return true;}}else if(u==qto){if(vist[qfrom]){System.out.println(find(qfrom));return true;}}// 还是没算出结果,向上回溯,准备去兄弟子树计算return false;}public static void main(String[] args) throws FileNotFoundException {//System.setIn(new FileInputStream(new File("POJ_1330.txt")));Scanner sc = new Scanner(System.in);int n = sc.nextInt();while (n-- > 0){int m = sc.nextInt();p = new int[m+1];head = new int[m+1];Arrays.fill(head,-1);edges = new Edge[m];vist = new boolean[m+1];isroot = new boolean[m+1];Arrays.fill(isroot,true);// 链式前向星构有向图for(int i=0;i<m-1;i++){int from = sc.nextInt();int to = sc.nextInt();Edge edge = new Edge();//加入一条from 到 to 的单向边edge.to=to;edge.next=head[from];edges[i]=edge;head[from]=i;// 有父节点的不是根isroot[to]=false;}qfrom = sc.nextInt();qto = sc.nextInt();// 找根int root=0;for(int i=1;i<isroot.length;i++){if(isroot[i]) {root = i;break;}}// 计算LCALCA(root);}}
}

最新文章

  1. 最好用的嵌入式网络C库、Lua库
  2. linux安装无线电软件,基于Linux的软件无线电系统软件平台的研究与实现
  3. Android Button Example-onClickListener-Intent
  4. OpenCMS integration with Spring MVC--reference
  5. 共识机制-权益证明 PoS
  6. dama数据管理知识体系指南_DAMA知识体系解读(6)数据操作管理
  7. java高级用法之:JNA类型映射应该注意的问题
  8. mysql codesmith_CodeSmith连接Mysql配置
  9. linux源码_从linux源码看epoll及epoll实战揭秘
  10. 带有Hibernate OGM的NoSQL –第三部分:在WildFly上构建REST应用程序
  11. zabbix mysql优化 my.cnf_zabbix数据库优化之数据库优化(二)
  12. 《大数据管理概论》一2.5 知识融合技术
  13. 2015与2016年终总结
  14. Android 分贝测试仪功能,华为移动终端开发
  15. 百度导航5.0之后的坑
  16. happen before
  17. 让代码审查扮演更好的角色
  18. html 5 压缩zip,Zip
  19. 教会AI认识麻将牌之实践篇
  20. JavaSE进阶318-331 构造方法习题

热门文章

  1. 网上免费打电话和国际长途
  2. oracle alert下的文件,Oracle 11g alert文件的变化 --
  3. MC9S12XEP100-RTI设置
  4. 如何将win7系统的电脑屏幕改成护眼的豆沙绿
  5. HDU 6319 Ascending Rating(单调队列)
  6. python程序设计语言中的小于等于号_Python(matplotlib)小于或等于tex中的符号
  7. ttest求pvalue_.net 调用R语言的函数(计算统计值pvalue 对应excel :ttest)
  8. 去掉office 2010在标题前就会出现小黑点。
  9. 为什么计算机不显示桌面工具栏,笔记本电脑开机后不显示桌面图标或任务栏怎么解决...
  10. Windows XP下使用 whoami 命令