首先有两个数组 in[],out[],分别记录dfs遍历每个节点的起始时间和结束时间,(时间其实就是一个编号,从一开始)
这样说有点抽象,举个例子
先给出上图的dfs代码,然后模拟
#include<bits/stdc++.h>
using namespace std;
int f[1000][1000];
int n,tot; //tot是全局变量,不随递归走
int in[1000],out[1000];
int vis[1000];
void dfs(int a)
{
in[a]=++tot;//节点遍历的时间,每个节点仅会被遍历一次
for(int i=1;i<=n;i++){
if(!vis[i]&&f[a][i]){
vis[i]=1;//遍历后做标记,以后就不再遍历
dfs(i);
}
}
out[a]=tot;//结束时间
}
int main()
{
int m;
cin>>n>>m;
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
f[x][y]=f[y][x]=1;
}
vis[2]=1;
dfs(2);//从节点2开始访问
for(int i=1;i<=n;i++){
cout<<in[i]<<" "<<out[i]<<endl;
}
}
递归遍历过程
dfs(2) 此时2开始被遍历,tot=1, in[2]=1
dfs(4) tot=2 in[4]=2
dfs(1) tot=3 in[1]=3
此时1无路可走,回溯,1结束遍历 out[1]=3 (回溯时tot不加)
回到4,接着走3
dfs(3) tot=4 in[3]=4
3无路可走,回溯,3结束遍历 out[3]=4
返回4,4接着走7
dfs(7) tot=5 in[7]=5
7无路可走,回溯,7结束遍历 out[7]=5
回到4,4无路可走,结束遍历 out[4]=5
........
结果是这样
很明显,根节点的区间包含子树中的所有节点的区间