树与图的深度优先遍历
void dfs(int x)
{
v[x]=1;//记录点x被访问过了
for(int i=head[x];i;i=next[i])//遍历x链接的边
{
int y=ver[i];
if(v[y])
continue;
dfs(y);
}
}
关于这里的ver数组的理解一开始有些偏差,后来又翻了一遍前面的邻接表才发现之前用数组表示的邻接表的理解有些偏差,这里的head[x]指的是链接x点的第一条边,这里的i都是边,ver数组是记录的点的编号,并不是点的值,关于点的权值另有edge数组表示
时间戳:
按照深度优先遍历的过程,按照每个节点第一 次被访问的顺序,依次给与这些点1~n的整数标记,这些标记就被称为时间戳,记为dfn。
树的dfs序:
对于某个节点在刚进入递归后即回溯前各记录一次该点的编号,最后产生长度为2n的节点序列为树的DFS序。
void dfs(int x)
{
a[++m]=x;//进入递归时标记
v[x]=1;//记录点x被访问过了
for(int i=head[x];i;i=next[i])//遍历x链接的边
{
int y=ver[i];
if(v[y])
continue;
dfs(y);
}
a[++m]=x;//回溯前记录
}
应用:每个节点在序列里恰好出现两次,设这两次出现的位置恰好是L[i],R[i],那么闭区间[L[I],R[I]]就是以i为根的子树的dfs序列,在很多与树相关的问题上,可以通过DFS序吧树统计转化为序列上的区间统计。
树的深度:
void dfs(int x)
{
v[x]=1;//记录点x被访问过了
for(int i=head[x];i;i=next[i])//遍历x链接的边
{
int y=ver[i];
if(v[y])
continue;
d[y]=d[x]+1;
dfs(y);
}
}
这没什么好说的,用个数组记录一下就行。
来源:https://blog.csdn.net/weixin_43244265/article/details/98885099