1.將最初訪問的頂點壓入棧;ios
2.只要棧中仍有頂點,就循環進行下述操做:數組
(1)訪問棧頂部的頂點u;函數
(2)從當前訪問的頂點u 移動至頂點v 時,將v 壓入棧。若是當前頂點u 不存在未訪問的相鄰矩陣,則將u 從棧中刪除;spa
color[n] | 用WHITE、GRAY、BLACK 中的一個來表示頂點i 的訪問狀態 |
M[n][n] | 鄰接矩陣, 若是存在頂點i 到頂點j 的邊,則M[i][j]爲true |
Stack S | 棧, 暫存訪問過程當中的頂點code |
其中color 數組中, 白色表明「未訪問的頂點」, 灰色表明「訪問過的頂點」(雖然被訪問過了,但仍然可能留有通往未訪問頂點的邊), 黑色表明」訪問結束的頂點」;blog
#include<stdio.h> #define N 100 #define WHITE 0 #define GRAY 1 #define BLACK 2 int n, M[N][N]; int color[N], d[N], f[N], tt;//color[n]表示該頂點訪問與否,d[n]表示該頂點的發現時刻 ,f[n]表示該頂點的結束時刻 ,tt表示時間 //用遞歸函數實現的深度優先搜索 void dfs_visit(int u) { int v; color[u] = GRAY; d[u] = ++tt; for(v = 0; v < n; v++) { if(M[u][v] == 0) continue; if(color[v] == WHITE) dfs_visit(v); } color[u] = BLACK; f[u] = ++tt;//訪問結束 } void dfs() { int u; //初始化 for(u = 0; u < n; u++) color[u] = WHITE; tt = 0; //以未訪問的u爲起點進行深度優先搜索 for(u = 0; u < n; u++) { if(color[u] == WHITE) dfs_visit(u); } //輸出 for(u = 0; u < n; u++) { printf("%d %d %d\n", u+1, d[u], f[u]); } } int main() { int u, v, k, i, j; scanf("%d", &n); //初始化 for(i = 0; i < n; i++) { for(j = 0; j < n; j++) { M[i][j] = 0; } } //輸入數據,構造鄰接矩陣 for(i = 0; i < n; i++) { scanf("%d %d", &u, &k); u--; for(j = 0; j < k; j++) { scanf("%d", &v); v--; M[u][v] = 1; } } dfs(); return 0; } /* 6 1 2 2 3 2 2 3 4 3 1 5 4 1 6 5 1 6 6 0 */
#include<iostream> #include<stack> using namespace std; static const int N = 100; static const int WHITE = 0; static const int GRAY = 1; static const int BLACK = 2; int n, M[N][N]; int color[N], d[N], f[N], tt;//color[n]表示該頂點訪問與否,d[n]表示該頂點的發現時刻 ,f[n]表示該頂點的結束時刻 int nt[N];//記錄每一個頂點的鄰接頂點偏移量,eg:頂點0有倆個頂點1,2;現已經訪問過1了,那麼, nt[u] = 1; 下次直接訪問2 //按編號順序獲取與u相鄰的v int next(int u) { for(int v = nt[u]; v < n; v++) { nt[u] = v + 1; if(M[u][v]) return v; } return -1; } void dfs_visit(int r) { for(int i = 0; i < n; i++) nt[i] = 0; stack <int> S; S.push(r); color[r] = GRAY; d[r] = ++tt; while( !S.empty() ) { int u = S.top(); int v = next(u); if(v != -1) { if(color[v] == WHITE) { color[v] = GRAY; d[v] = ++tt; S.push(v); } } else { S.pop(); color[u] = BLACK; f[u] = ++tt; } } } void dfs() { //初始化 for( int i = 0; i < n; i++) { color[i] = WHITE; nt[i] = 0; } //設置時間 tt = 0; //以未訪問的u爲起點進行深度優先搜索,設置循環的目的應該是防止該圖不是連通圖 for(int u = 0; u < n; u++) { if(color[u] == WHITE) dfs_visit(u); } for(int i = 0; i < n; i++) { cout << i+1 << " " << d[i] << " " << f[i] << endl; } } int main() { int u, k, v; cin >> 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++) { cin >> u >> k;//輸入頂點和頂點的度 u--; for(int j = 0; j < k; j++) { cin >> v; v--; M[u][v] = 1; } } dfs(); return 0; } /* 6 1 2 2 3 2 2 3 4 3 1 5 4 1 6 5 1 6 6 0 */