题目如下
DFS对每个顶点的时间戳如下:
- d[v]:记录v首次发现的时刻
- f [v]:记录搜索完v的所有邻接点的时刻
对于有n个顶点、m条边(1≤n≤50,0≤m≤200)的有向图G,计算所有顶点的时间戳。(顶点编号范围[0, n),时间戳从1开始)
当DFS有多个候选访问时,算法应该选择编号小的顶点。
输入格式:
在第一行中,给出了表示G的顶点数的整数n。
在接下来的n行中,顶点u的邻接表均以下列格式提供:u k v1 v2 ... vk
u为顶点的编号,k为u的出度。vi是与u相邻的顶点编号。数据保证vi以升序给出。
输出格式:
对于每个顶点,在一行中打印编号、d和f,中间用一个空格分隔。d和f分别为发现时间和完成时间。按顶点编号的顺序打印。
输入样例:
4
0 1 1
1 1 3
2 0
3 1 2
输出样例:
0 1 8
1 2 7
2 4 5
3 3 6
答案部分:
运用DFS深度优先搜索 遍历
深度优先搜索算法(Depth First Search,简称DFS):一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过或者在搜寻时结点不满足条件,搜索将回溯到发现节点v的那条边的起始节点。整个进程反复进行直到所有节点都被访问为止。属于盲目搜索,最糟糕的情况算法时间复杂度为O(!n)。
#include<stdio.h>
#define GRAY 1
#define Z 100
#define BLACK 2
#define WHITE 0
int n, M[Z][Z];
int color[Z], d[Z], f[Z], tt;
void dfsvisit(int u);
void dfs();
int main(){
int u, v, k;
scanf("%d", &n);
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++) M[i][j] = 0;
}
for(int i = 0; i < n; i++){
scanf("%d %d", &u, &k);
for(int j = 0; j < k; j++){
scanf("%d", &v);
M[u][v] = 1;
}
}dfs();
return 0;
}
void dfsvisit(int u){
color[u] = GRAY;
d[u] = ++tt;
for(int v = 0; v < n; v++){
if(M[u][v] == 0) continue;
if(color[v] == WHITE){
dfsvisit(v);
}
}
color[u] = BLACK;
f[u] = ++tt;
}
void dfs(){
for(int u = 0; u < n; u++) color[u] = WHITE;
tt = 0;
for(int u = 0; u < n; u++){
if(color[u] == WHITE) dfsvisit(u);
}
for(int u = 0; u < n; u++){
printf("%d %d %d\n", u , d[u], f[u]);
}
}