题意:给你一棵树,求两个点的最近公共祖先。

思路:因为只有一组询问,直接数组模拟好了。

(写得比较乱)

原题请戳这里

#include <cstdio>
#include <bitset>
#include <cstring>
#include <algorithm>
using namespace std;
int first[10005],v[10005],next[10005];
int main()
{
int cas;
scanf("%d",&cas);
while(cas--)
{
bitset<10005> b;
memset(first,-1,sizeof(first));
int tot=1,n,x,s,e;
scanf("%d",&n);
for(int i=1;i<n;i++)
{
scanf("%d%d",&v[tot],&x);
next[i]=first[x];
first[x]=tot++;
}
scanf("%d%d",&s,&e);
b.flip(s);
while(first[s]!=-1)
{
s=v[first[s]];
b.flip(s);
}
if(b.test(e))
{
printf("%d\n",e);
goto end;
}
while(first[e]!=-1)
{
e=v[first[e]];
if(b.test(e))
{
printf("%d\n",e);
break;
}
}
end:;
}
}

搞个Tarjan玩玩

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int first[10005],cas,next[10005],v[10005],s,e,ans,f[10005];
bool vis[10005];
int find(int x)
{
return f[x]==x?x:f[x]=find(f[x]);
}
void Tarjan(int x)
{
f[x]=x;
for(int i=first[x];~i;i=next[i])
{
Tarjan(v[i]);
f[find(v[i])]=x;
}
vis[x]=1;
if(x==s&&vis[e])
{
ans=find(e);
}
else if(x==e&&vis[s])
{
ans=find(s);
}
}
int main()
{
scanf("%d",&cas);
while(cas--)
{
memset(first,-1,sizeof(first));
memset(vis,0,sizeof(vis));
int tot=1,n,x,root;
scanf("%d",&n);
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&v[tot]);
next[i]=first[x];
vis[v[tot]]=1;
first[x]=tot++;
}
for(int i=1;i<=n;i++)
{
if(!vis[i])
{
root=i;
break;
}
}
memset(vis,0,sizeof(vis));
scanf("%d%d",&s,&e);
Tarjan(root);
printf("%d\n",ans);
}
}



(对于这道题,还是模拟大法好啊)

如果给多组询问,就只能用Tarjan或者ST了。。

ST的:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int cases,root,n,jyx,jyy,tot,fa[100005][19];
int in[100005],dep[100005],first[100005],next[100005],v[100005];
void add(int x,int y){
v[tot]=y;
next[tot]=first[x];
first[x]=tot++;
}
void dfs(int x)
{
for(int i=1;i<=18;i++)
{
fa[x][i]=fa[fa[x][i-1]][i-1];
}
for(int i=first[x];~i;i=next[i])
{
dep[v[i]]=dep[x]+1;
dfs(v[i]);
}
}
int lca(int x,int y)
{
if(dep[x]<dep[y])swap(x,y);
for(int i=18;i>=0;i--)
{
if(dep[x]>=dep[y]+(1<<i))x=fa[x][i];
if(x==y)return x;
}
for(int i=18;i>=0;i--)
{
if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
}
return fa[x][0];
}
int main()
{
scanf("%d",&cases);
while(cases--){
memset(first,-1,sizeof(first));
memset(in,0,sizeof(in));
tot=0;
scanf("%d",&n);
for(int i=1;i<n;i++){
scanf("%d%d",&jyx,&jyy);
fa[jyy][0]=jyx;
add(jyx,jyy);
in[jyy]++;
}
scanf("%d%d",&jyx,&jyy);
for(int i=1;i<=n;i++)if(!in[i])root=i;
dfs(root);
printf("%d\n",lca(jyx,jyy));
}
}

POJ 1330 Tarjan LCA、ST表(其实可以数组模拟)的更多相关文章

  1. 51nod 1766 树上的最远点对 | LCA ST表 线段树 树的直径

    51nod 1766 树上的最远点对 | LCA ST表 线段树 树的直径 题面 n个点被n-1条边连接成了一颗树,给出a~b和c~d两个区间,表示点的标号请你求出两个区间内各选一点之间的最大距离,即 ...

  2. poj 1330(RMQ&LCA入门题)

    传送门:Problem 1330 https://www.cnblogs.com/violet-acmer/p/9686774.html 参考资料: http://dongxicheng.org/st ...

  3. POJ 3264 Balanced Lineup | st表

    题意: 求区间max-min st表模板 #include<cstdio> #include<algorithm> #include<cstring> #inclu ...

  4. st表树状数组入门题单

    预备知识 st表(Sparse Table) 主要用来解决区间最值问题(RMQ)以及维护区间的各种性质(比如维护一段区间的最大公约数). 树状数组 单点更新 数组前缀和的查询 拓展:原数组是差分数组时 ...

  5. BZOJ 4556: [Tjoi2016&Heoi2016]字符串(后缀数组 + 二分答案 + 主席树 + ST表 or 后缀数组 + 暴力)

    题意 一个长为 \(n\) 的字符串 \(s\),和 \(m\) 个询问.每次询问有 \(4\) 个参数分别为 \(a,b,c,d\). 要你告诉它 \(s[a...b]\) 中的所有子串 和 \(s ...

  6. poj 1330(初探LCA)

    Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 23795   Accept ...

  7. POJ 1330 (LCA)

    http://poj.org/problem?id=1330 题意:给出一个图,求两个点的最近公共祖先. sl :水题,贴个模板试试代码.本来是再敲HDU4757的中间发现要用LCA,  操蛋只好用这 ...

  8. POJ 1330(LCA/倍增法模板)

    链接:http://poj.org/problem?id=1330 题意:q次询问求两个点u,v的LCA 思路:LCA模板题,首先找一下树的根,然后dfs预处理求LCA(u,v) AC代码: #inc ...

  9. Nearest Common Ancestors POJ - 1330 (LCA)

    Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 34657   Accept ...

随机推荐

  1. Linux添加FTP用户并设置权限

    在linux中添加ftp用户,并设置相应的权限,操作步骤如下: 1.环境:ftp为vsftp.被限制用户名为test.被限制路径为/home/test 2.建用户,命令行状态下,在root用户下: 运 ...

  2. CAD动态绘制样条线(com接口)

    主要用到函数说明: _DMxDrawX::SendStringToExecuteFun 把命令当着函数执行,可以传参数.详细说明如下: 参数 说明 IDispatch* pParam 命令参数,IMx ...

  3. 基于owncloud构建私有云储存网盘

    注意事项:需要ping通外网 需要LAMP架构yum -y install httpd php php-mysql mariadb-server mariadb sqlite php-dom php- ...

  4. 发现是在IE6-IE9下,下列元素table,thead,tfoot,tbody,tr,col,colgroup,html,title,style,frameset的innerHTML属性是只读的

     table ID="zhutiTable" html2="<tr></tr>": 的数据 setTableInnerHTML(docu ...

  5. Win32中 DLL、Lib 库的创建机器使用

    Windows 下 的静态库和动态库 一.静态函数库(Lib) 1. 静态函数库的制作(C/C++) —— 打开新建项目,然后选中Win32项目,接着在创建项目中选择 Lib,再接着将函数.实现功能的 ...

  6. java折半插入排序

    代码如下: public class BinaryInsertSort { public static void binaryInsertSort(DataWrap [] data) { System ...

  7. linux下root用户和tarena用户vimrc配置

    设置vim自动缩进,行号,tab键宽度 如果是root超级用户,他的主目录是: /root ,打开文件vim的配置文件.vimrc 如果是tarena用户,他的主目录是:/home/tarena 打开 ...

  8. Emacs的undo与redo

    在Emacs的手册16.1节中有这样一句话, Any command other than an undo command breaks the sequence of undo commands. ...

  9. 前端开发神器之chrome 综述

    作为前端工程师,也许你对chrome开发工具不陌生,但也谈不上对各个模块有深入了解. 本文主要是为chrome开发工具使用这个系列做个开篇. 参考资料: 谷歌开发者: https://develope ...

  10. 【Codeforces 1114B】Yet Another Array Partitioning Task

    [链接] 我是链接,点我呀:) [题意] 让你把数组分成k个连续的部分 使得每个部分最大的m个数字的和最大 [题解] 把原数组降序排序 然后选取前m*k个数字打标记 然后对于原数组 一直贪心地取 直到 ...