DFS序
1、什么是DFS序
DFS算法:深度优先搜索遍历,所以DFS序就是使用深度优先搜索遍历一颗树所经过的节点顺序。比如下面这张图中的树,它的DFS序为:1->3->6->8->8->6->3->2->5->7->7->5->4->4->2->1
2、DFS序的性质和作用
DFS序列的一些性质:
(1)还没搞懂,等搞懂了再来补充。。。
DFS序的作用:
(1)等我做点题在回来写。。。
3、DFS算法
提示:所有算法均采用数据结构链式向前星
DFS算法
当然也可以只传递一个参数x,不过这样的话要添加一个数据vis[N],记录N个节点那个被访问了。
void dfs(int x, int father)
{
cout << x << " "; //输出节点
int to;
for(int i = head[x]; i; i = edges[i].next)
{
to = edges[i].to;
if(to != father)
dfs(to, x);
}
}
4、时间戳
时间戳记录第一次开始访问这个节点的时间和最后结束访问的时间
void dfs(int x, int father)
{
NewIdx[cnt_n] = x;//dfs序列
InOut[cnt_n] = 1;//记录第cnt_n个节点的开始访问和结束访问,1:开始访问,-1结束访问。
InIdx[x] = cnt_n ++;//x节点开始访问的时间,也就是在dfs序中的位置
int to;
for(int i = head[x]; i; i = edges[i].next)
{
to = edges[i].to;
if(to != father)
dfs(to, x);
}
NewIdx[cnt_n] = x;
InOut[cnt_n] = -1;
OutIdx[x] = cnt_n ++;//x节点结束访问的时间。
}
5、完整代码
#include<bits/stdc++.h>
using namespace std;
const int M = 300 + 5;
int head[M];
int cnt_edge = 1;
int n; //节点数
int cnt_n = 0; //节点数
int NewIdx[M * 2];//dfs序,节点访问的序列
int InOut[M * 2];//第 cnt_n 个节点是开始访问还是最后访问
int InIdx[M * 2];//开始访问节点的时间,也就是节点 x 在NewIdx中的位置
int OutIdx[M * 2];//结束访问节点的时间
struct Edge{
int to;
int next;
}edges[2 * M];
void add(int from, int to)
{
edges[++ cnt_edge].to = to;
edges[cnt_edge].next = head[from];
head[from] = cnt_edge;
}
void dfs(int x, int father)
{
cout << x << "->";
NewIdx[cnt_n] = x;
InOut[cnt_n] = 1;
InIdx[x] = cnt_n ++;
int to;
for(int i = head[x]; i; i = edges[i].next)
{
to = edges[i].to;
if(to != father)
dfs(to, x);
}
cout << x << "->";
NewIdx[cnt_n] = x;
InOut[cnt_n] = -1;
OutIdx[x] = cnt_n ++;
}
int main()
{
cin >> n;
int x, y;
for(int i = 1; i < n; ++ i)
{
cin >> x >> y;
add(x, y);
add(y, x);
}
dfs(1, 0);
return 0;
}