【RMQ&am 4000 p;amp;LCA】Nearest Common Ancest…
2015-02-02 19:25
253 查看
【RMQ&LCA】Nearest Common
Ancestors(最近公共祖先)
Time Limit:1000MS Memory
Limit:65536KTotal Submit:4 Accepted:4
Description
最近公共祖先(lca.pas/c/cpp)【问题描述】 有根树是一个在计算机科学和工程学中众所周知的数据结构。如下图所示的例子: 在上图,每个结点用1-16中的一个整数标记。结点8是这棵树的根。
一个结点x是一个结点y的祖先当且仅当结点x是在根和结点y的路径上。例如,结点4是结点16的祖先,结点10也是结点16的祖先。实际上,结点8,4和12都是结点16的祖先。记住每个结点都是它自己的祖先。结点8,4,6和7都是结点7的祖先。 一个结点x被称做结点y和z的公共祖先当且仅当x都是y和z的祖先。因此,结点8 和4是结点16和7的公共祖先。
一个结点x被称做结点y和z的最近公共祖先当且仅当x是y和z的一个公共祖先且在y和z的所有公共祖先中是最近的。所以,结点16和7的最近公共祖先是结点4,因为结点4比结点8更接近结点16和7。
在其它例子中,结点2和3的最近公共祖先结点10,结点6和13的最近公共祖先是结点8,结点4和12的最近公共祖先是结点4。在最后的一个例子中,如果y是z的一个祖先,那么y和z的最近公共祖先是y。 写一个程序找出在一棵树中两个不同结点的最近公共祖先。Input
输入包括T组数据。第一行是一个整数T。对每组数据,第一行是一个整数N,表示这棵树的结点数,其中2<=N<=10,000。这些结点标记为1,2,…,N。接下来的N-1行包括一对整数,代表一条边,第一个数是第二个数的父亲。保证N个结点恰好有N-1条边。最后的一行包括两个不同的整数,表示要求最近公共祖先的两个不同结点Output
对每组数据输出一行,包括一个表示所求的两个不同结点的最近公共祖先的整数Sample
Input
Sample
Output
Hint
本题数据不完整,请在本系统测试通过后到http://poj.org/problem?id=1330
提交完整测试!Source
Taejon 2002 这题可以说是下一题的化简版本,下一题要用到ST算法,而这题直接枚举就行了。具体解题报告请看下一题。var m,n,nf,father,j,l,r:longint; f,d:array[0..20001]of longint; tree:array[1..10001,0..101]of longint;procedure init;var i,x,y:longint; mark:array[1..10001]of boolean;begin fillchar(mark,sizeof(mark),0); fillchar(tree,sizeof(tree),0); fillchar(f,sizeof(f),0); fillchar(d,sizeof(d),0); read(n); for i:=1 to n-1 do begin read(x,y); inc(tree[x,0]); tree[x,tree[x,0]]:=y; mark[y]:=true; end; read(l,r); for i:=1 to n do if not mark[i] then begin father:=i; exit; end;end;procedure dfs(fa,de:longint);var i:longint;begin inc(f[0]); f[f[0]]:=fa; d[f[0]]:=de; for i:=1 to tree[fa,0] do begin dfs(tree[fa,i],de+1); inc(f[0]); f[f[0]]:=fa; d[f[0]]:=de; end;end;function min(x,y:longint):longint;begin if x<y then exit(x)
else exit(y);end;procedure main;var i,t,b,ll,rr,minn,mini:longint;begin nf:=2*n-1; for i:=1 to nf do if f[i]=l then begin ll:=i; break; end; for i:=1 to nf do if f[i]=r then begin rr:=i; break; end; if rr<ll then begin rr:=rr+ll; ll:=rr-ll; rr:=rr-ll; end; minn:=maxlongint; for i:=ll to rr do if d[i]<minn then begin
minn:=d[i]; mini:=i; end; writeln(f[mini]);end;begin read(m); for j:=1 to m do begin init; dfs(father,0); main; end;end.
Ancestors(最近公共祖先)
Time Limit:1000MS Memory
Limit:65536KTotal Submit:4 Accepted:4
Description
最近公共祖先(lca.pas/c/cpp)【问题描述】 有根树是一个在计算机科学和工程学中众所周知的数据结构。如下图所示的例子: 在上图,每个结点用1-16中的一个整数标记。结点8是这棵树的根。
一个结点x是一个结点y的祖先当且仅当结点x是在根和结点y的路径上。例如,结点4是结点16的祖先,结点10也是结点16的祖先。实际上,结点8,4和12都是结点16的祖先。记住每个结点都是它自己的祖先。结点8,4,6和7都是结点7的祖先。 一个结点x被称做结点y和z的公共祖先当且仅当x都是y和z的祖先。因此,结点8 和4是结点16和7的公共祖先。
一个结点x被称做结点y和z的最近公共祖先当且仅当x是y和z的一个公共祖先且在y和z的所有公共祖先中是最近的。所以,结点16和7的最近公共祖先是结点4,因为结点4比结点8更接近结点16和7。
在其它例子中,结点2和3的最近公共祖先结点10,结点6和13的最近公共祖先是结点8,结点4和12的最近公共祖先是结点4。在最后的一个例子中,如果y是z的一个祖先,那么y和z的最近公共祖先是y。 写一个程序找出在一棵树中两个不同结点的最近公共祖先。Input
输入包括T组数据。第一行是一个整数T。对每组数据,第一行是一个整数N,表示这棵树的结点数,其中2<=N<=10,000。这些结点标记为1,2,…,N。接下来的N-1行包括一对整数,代表一条边,第一个数是第二个数的父亲。保证N个结点恰好有N-1条边。最后的一行包括两个不同的整数,表示要求最近公共祖先的两个不同结点Output
对每组数据输出一行,包括一个表示所求的两个不同结点的最近公共祖先的整数Sample
Input
Sample
Output
Hint
本题数据不完整,请在本系统测试通过后到http://poj.org/problem?id=1330
提交完整测试!Source
Taejon 2002 这题可以说是下一题的化简版本,下一题要用到ST算法,而这题直接枚举就行了。具体解题报告请看下一题。var m,n,nf,father,j,l,r:longint; f,d:array[0..20001]of longint; tree:array[1..10001,0..101]of longint;procedure init;var i,x,y:longint; mark:array[1..10001]of boolean;begin fillchar(mark,sizeof(mark),0); fillchar(tree,sizeof(tree),0); fillchar(f,sizeof(f),0); fillchar(d,sizeof(d),0); read(n); for i:=1 to n-1 do begin read(x,y); inc(tree[x,0]); tree[x,tree[x,0]]:=y; mark[y]:=true; end; read(l,r); for i:=1 to n do if not mark[i] then begin father:=i; exit; end;end;procedure dfs(fa,de:longint);var i:longint;begin inc(f[0]); f[f[0]]:=fa; d[f[0]]:=de; for i:=1 to tree[fa,0] do begin dfs(tree[fa,i],de+1); inc(f[0]); f[f[0]]:=fa; d[f[0]]:=de; end;end;function min(x,y:longint):longint;begin if x<y then exit(x)
else exit(y);end;procedure main;var i,t,b,ll,rr,minn,mini:longint;begin nf:=2*n-1; for i:=1 to nf do if f[i]=l then begin ll:=i; break; end; for i:=1 to nf do if f[i]=r then begin rr:=i; break; end; if rr<ll then begin rr:=rr+ll; ll:=rr-ll; rr:=rr-ll; end; minn:=maxlongint; for i:=ll to rr do if d[i]<minn then begin
minn:=d[i]; mini:=i; end; writeln(f[mini]);end;begin read(m); for j:=1 to m do begin init; dfs(father,0); main; end;end.
相关文章推荐
- 【RMQ&LCA】Nearest Common Ancest…
- 【RMQ&LCA】Closest Common Ancest…
- POJ - 1330 Nearest Common Ancestors(LCA最近公共祖先 朴素算法&倍增法)
- poj 1330 Nearest Common Ancestors(LCA 基于二分搜索+st&rmq的LCA)
- POJ 1330 Nearest Common Ancestors (LCA&Tarjan算法)
- poj 1330 Nearest Common Ancestors 裸的LCA
- 【RMQ&LCA】运动员的身高 解题报告…
- POJ 1330 Nearest Common Ancestors(LCA 可以用ST算法 NlogN 或者简单搜索)
- POJ 1330 Nearest Common Ancestors(LCA 在线算法)
- Common Trouble Solution--CASE NE…
- poj--1330 Nearest Common Ancestors(LCA/Tarjan)
- POJ 1330 Nearest Common Ancestors(LCA)
- poj----1330Nearest Common Ancestors(简单LCA)
- POJ1330 Nearest Common Ancestors【最近公共祖先】【Tarjan-LCA算法】
- POJ1330 Nearest Common Ancestors(在线倍增,离线Tarjan,最近公共祖先LCA)
- poj 1330 Nearest Common Ancestors(LCA)
- ACM: 最近公共祖先问题LCA 图论题 …
- POJ 1330 Nearest Common Ancestors(LCA,在线处理三种方式)
- POJ 1330 Nearest Common Ancestors (LCA,dfs+ST在线算法)
- POJ题目1330 Nearest Common Ancestors(LCA)