DFS序
什么是DFS序呢?顾名思义,深搜序号。不要小瞧他,若运用得当,在线段树等实现中,是可以省空间的。
首先,对于一张图的DFS,我们是知道的。
void dfs(int x)
{
vis[x]=true;//标记已来过
for(int i=head[x];i;i=e[i].next)//链式前向星
{
int v=e[i].to;
if(vis[v]) continue;
dfs(v);
}
}
这段代码访问每个点和每条边恰好一次(如果是无向边,正反方向各访问一次)
按照上述的DFS过程,以每个节点第一次被访问时的顺序,依次编号1-N,该标记就被称为时间戳,记为dfn(随你)
以此图为例,很好理解:
in[1]=1;
in[2]=2;
in[8]=3;
in[5]=4;
in[7]=5;
in[4]=6;
in[3]=7;
in[9]=8;
in[6]=9;
这样还不是很方便,我们需要记录多一点的信息。
两个时间戳:in[ ],out[ ](进来和出去)
所以刚才那张图应该是这样:
前一个代表in,后一个就是out
不难看出,此时每个节点对应了一个区间,而且可以看到,每个节点对应的区间正好“管辖”了它子树所有节点的区间。
int cnt=0;
void dfs(int x)
{
vis[x]=true;//已来过
in[x]=++cnt;//进来时间戳
num[cnt]=x;//转化成新序列
for(int i=head[x];i;i=e[i].next)
{
int v=e[i].to;
if(vis[v]) continue;
dfs(v);
}
out[x]=cnt;//出去时间戳
}
其实这就是DFS序,看似很简单~~~~