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

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

(写得比较乱)

原题请戳这里

#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. numpy.tile()

    numpy.tile()是个什么函数呢,说白了,就是把数组沿各个方向复制 比如 a = np.array([0,1,2]),    np.tile(a,(2,1))就是把a先沿x轴(就这样称呼吧)复制 ...

  2. strcpy & memcpy区别

    这两个经常使用的函数,主要区别有: strcpy 返回值是char *, strcpy(x1, x2); x1 x2必须都是char* 类型 memcpy(x1, x2, sizeof(xx)); m ...

  3. 总结这几天js的学习内容

    对js中难点的理解 1.把变量对象像遍历数组一样简单 对于数组 ,迭代出来的是数组元素,对于对象 ,迭代出来的是对象的属性: var obj = { w: "wen", j: &q ...

  4. Luogu P1550 打井Watering Hole

    P1550 [USACO08OCT]打井Watering Hole 题目背景 John的农场缺水了!!! 题目描述 Farmer John has decided to bring water to ...

  5. sqlalchemy子查询

    使用subquery() 要使用c来定位上一个子句的属性 s1 = session.query(m.a,m.b).filter().subquery() s2 = session.query(s1.c ...

  6. 通过git向github提交项目

    按顺序学习 https://www.cnblogs.com/forget406/p/6045499.html#top https://blog.csdn.net/xiaoputao0903/artic ...

  7. Scrapy实战:爬取http://quotes.toscrape.com网站数据

    需要学习的地方: 1.Scrapy框架流程梳理,各文件的用途等 2.在Scrapy框架中使用MongoDB数据库存储数据 3.提取下一页链接,回调自身函数再次获取数据 重点:从当前页获取下一页的链接, ...

  8. 小白神器 - 一篇博客学会CSS

    一. 简介 1. css定义 CSS是Cascading Style Sheets的简称,中文称为层叠样式表. 属性和属性值用冒号隔开,以分号结尾. 2. 四种引入方式 1.行内式   行内式是在标签 ...

  9. 学习记录--让我打开另一种思路的SQL

    1.显示文章.提交人和最后回复时间 select a.title,a.username,b.adddate from table a, (select max(adddate) adddate fro ...

  10. hdu2014 青年歌手大奖赛_评委会打分【C++】

    青年歌手大奖赛_评委会打分 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tot ...