Closest Common Ancestors (Lca,tarjan)

午时刷题,难甚,遂小憩于桌上,惊醒,于梦中有所得,虽大声曰:吾已得tarjan之奥秘!
关于tarjan算法,其实就是一个递归加并查集的应用。
大致代码:
#include<bits/stdc++.h>
using namespace std;
int find(int x){
....
} void join(int x,int y)
{
....
}
void dfs(int x)
{
int len=v[x].size();
for(int i=; i<len; i++) //遍历x的子节点
{
dfs(v[x][i]); //继续往下推
join(v[x][i],x); //将x的所有子节点的祖先都设为x
}
vis[x] = true; //证明x走过了
for(int i=; i<=n; i++) //对每个x循环1~n
if(vis[i]&&g[x][i]) //如果i已经走过并且要求(x,i)
ans=find(i); //lca就是ans
}
由以上代码可以看出,tarjan实际上就是并查集与dfs的结合,其最核心的部分就是dfs那部分
只要理解了dfs()的内容,就能理解tarjan
而对于dfs函数,我们首先就会想到它的特性:不撞南墙不回头。
假如有一颗树,对其dfs,那么首先它会沿着一个分支一直到尽头(如图):

而当走到4这个点时,函数开始执行下列语句:
join(v[x][i],x); //将x的所有子节点的祖先都设为x
//而此时pre[4]=3;pre[3]=3;pre[2]=2;pre[1]=1;
再然后是:
vis[x] = true; //证明x走过了
for(int i=1; i<=n; i++) //对每个x循环1~n
if(vis[i]&&g[x][i]) //如果i已经走过并且要求(x,i)
ans=find(i); //lca就是ans
}
如果存在要求lca[x][i],先看i点是否走过,如果走过,那就只有一种可能(真相只有一个!真実はいつも一つ):

i,k必在两条不同分支上,并且交于某个点x,如果i已经走过了,那么,i所在的这条分支上所有的点都有明确的父子关系,即find(i)==x!
代码参上:
#pragma GCC optimize(2)
#include<stdio.h>
#include<string.h>
#include<vector>
#define M 1007
using namespace std;
int g[M][M],in[M],pre[M],cnt[M];
bool vis[M];
vector<int>v[M];
int n,m;
void init()
{
memset(g,,sizeof(g));
memset(in,,sizeof(in));
memset(cnt,,sizeof(cnt));
memset(vis,false,sizeof(vis));
for(int i=; i<=n; i++)
{
v[i].clear();
pre[i]=i;
}
}
int fond(int x)
{
return x==pre[x]?x:pre[x]=fond(pre[x]);
}
void join(int x,int y)
{
int xx=fond(x);
int yy=fond(y);
pre[xx]=yy;
}
void dfs(int x)
{
int len=v[x].size();
for(int i=; i<len; i++) //遍历x的子节点
{
dfs(v[x][i]); //继续往下推
join(v[x][i],x); //将x的所有子节点的祖先都设为x
}
vis[x] = true; //证明x走过了
for(int i=; i<=n; i++) //对每个x循环1~n
if(vis[i]&&g[x][i]) //如果i已经走过并且要求(x,i)
cnt[fond(i)]+=g[x][i]; //
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
init();
int a,b,c,root;
for(int i=; i<=n; i++)
{
scanf("%d:(%d)",&a,&b);
while(b--)
{
scanf(" %d",&c);
v[a].push_back(c);
in[c]++;
}
}
scanf("%d",&m);
getchar();
while(m--)
{
scanf("(%d,%d)",&a,&b);
getchar();
g[a][b]++;
g[b][a]++;
}
for(int i=; i<=n; i++)
if(!in[i])
{
root=i;
break;
}
dfs(root);
for(int i=; i<=n; i++)
{
if(cnt[i])
printf("%d\n",i);
}
}
return ;
}
以上;
Closest Common Ancestors (Lca,tarjan)的更多相关文章
- poj 1470 Closest Common Ancestors LCA
题目链接:http://poj.org/problem?id=1470 Write a program that takes as input a rooted tree and a list of ...
- POJ1470 Closest Common Ancestors 【Tarjan的LCA】
非常裸的模版题,只是Tarjan要好好多拿出来玩味几次 非常有点巧妙呢,tarjan,大概就是当前结点和它儿子结点的羁绊 WA了俩小时,,,原因是,这个题是多数据的(还没告诉你T,用scanf!=EO ...
- POJ 1470 Closest Common Ancestors(LCA&RMQ)
题意比较费劲:输入看起来很麻烦.处理括号冒号的时候是用%1s就可以.还有就是注意它有根节点...Q次查询 在线st算法 /*************************************** ...
- POJ 1470 Closest Common Ancestors(LCA 最近公共祖先)
其实这是一个裸求LCA的题目,我使用的是离线的Tarjan算法,但是这个题的AC对于我来说却很坎坷……首先是RE,我立马想到数组开小了,然后扩大了数组,MLE了……接着把数组调整适当大小,又交了一发, ...
- POJ 1470 Closest Common Ancestors LCA题解
本题也是找LCA的题目,只是要求多次查询.一般的暴力查询就必定超时了,故此必须使用更高级的方法,这里使用Tarjan算法. 本题处理Tarjan算法,似乎输入处理也挺麻烦的. 注意: 由于查询的数据会 ...
- POJ 1470 Closest Common Ancestors (LCA,离线Tarjan算法)
Closest Common Ancestors Time Limit: 2000MS Memory Limit: 10000K Total Submissions: 13372 Accept ...
- poj1470 Closest Common Ancestors [ 离线LCA tarjan ]
传送门 Closest Common Ancestors Time Limit: 2000MS Memory Limit: 10000K Total Submissions: 14915 Ac ...
- POJ 1470 Closest Common Ancestors 【LCA】
任意门:http://poj.org/problem?id=1470 Closest Common Ancestors Time Limit: 2000MS Memory Limit: 10000 ...
- poj----(1470)Closest Common Ancestors(LCA)
Closest Common Ancestors Time Limit: 2000MS Memory Limit: 10000K Total Submissions: 15446 Accept ...
随机推荐
- 系统信息的管理函数API
1.Windows系统信息 1.1获取系统版本: BOOL WINAPI GetVersionEx( __in_out LPOSVERSIONINFO lpVersionInfo ); lpVer ...
- ECMAScript 提案阶段
stage0 strawman任何讨论.想法.改变或者还没加到提案的特性都在这个阶段.只有TC39成员可以提交. stage1 proposal (1)产出一个正式的提案. (2)发现潜在的问题,例如 ...
- jenkins自动化部署gitlab上maven程序
部署流程:将代码从gitlab上拉取下来,使用maven打包,将打包后的jar通过ssh发送到服务器上,运行jar程序 注意:本文需要安装一些插件Publish Over SSH 1.新建任务 在主页 ...
- 【git 命令总结】一
git help config init commit diff rename mv rm head revert reset branch checkout branch-diff fast-for ...
- RAFT选举算法-分布式数据库困惑
在做HIS研发工作的时候一直想完善其数据组件,想做一个分布式的数据库支持系统.但一直以来都不清楚这个选举算法应怎么做,原来有一个叫raft的算法https://www.cnblogs.com/just ...
- mysql用户与授权
视图 create view 视图名 as 查询语句: MariaDB [hellodb]> create view view_left as select name from stude ...
- 【Python】对我自己的博客进行统计,看看哪年哪月发帖量最大
代码很简单,主要利用了requests进行网络访问,beautifulSoup进行页面文本分析,re进行正则表达式抽取文字,前面两个需要pip install name去安装,后者是内部对象所以不用安 ...
- AnimationDrawable
①先定义一个AnimationDrawable的xml资源文件: <?xml version="1.0" encoding="utf-8"?> &l ...
- [Java复习] Spring 常见面试问题
1. 什么是 Spring 框架?Spring 框架有哪些主要模块? 轻量级实现IoC和AOP的JavaEE框架. Core模块: bean(bean定义创建解析), context(环境, IoC容 ...
- 关于Java 8新引入语法特性的简要说明
Java 8在语法上的主要改进就是新增了Lambda Expression以及Method Reference.由于官方网站的介绍稍显罗嗦,而且例子也有些复杂.我这里将提供一些更为浅显.直观的例子来帮 ...