有向圖的DFS遍歷及判斷是否有環(演算法導論)
阿新 • • 發佈:2019-02-20
程式碼與10月22號已更正, 多謝:
#include <iostream> #include <cstdio> #include <vector> #include <cstring> #include <string> #include <algorithm> using namespace std; const int MAX = 1000; int color[MAX]; int Time; bool is_DAG; // 分別是時間撮,是否有環 int first[MAX],last[MAX]; // 最先被訪問的時間撮,結束訪問的時間撮 #define CLR(arr,val) memset(arr,val,sizeof(arr)) typedef struct { char v[MAX]; vector<int> map[MAX]; int vNum; // 節點數量 int eNum; // 邊的數量 }graph; //頂點顏色表 color[u] // 0 白色,未被訪問過的節點標白色 // -1 灰色,已經被訪問過一次的節點標灰色 // 1 黑色,已經被訪問過了(它的後代也全部被訪問過了) void Create(graph * g); // 建立圖 void DFS(graph *g);//深度優先遍歷圖g void dfs(graph *g,int curPoint);//從頂點i開始深度優先遍歷與其相鄰的點 void Create(graph *g) { for(int i = 0;i < g->eNum;i++) { int u,v; //第一個點是點0, 不是點1 cin>>u>>v; g->map[u].push_back(v); } } void dfs(graph *g,int curPoint ) { cout << "正在訪問節點 : " << curPoint<<endl; color[curPoint] = -1; // 標記此點位灰色 Time ++; first[curPoint] = Time; for(unsigned int i = 0 ; i < g->map[curPoint].size();i++) //遍歷所有和curPoint相連的點 { int now = g->map[curPoint][i]; if(color[now] == 0) // 如果點為白色 dfs(g,now); else if(color[now] == -1) is_DAG = false; // 訪問到了反向邊,那麼就是有環了 } color[curPoint] = 1; //標記為黑色, 說明點curPoint及其後代被訪問過了 cout << "節點" << curPoint << "訪問結束" <<endl; last[curPoint] = ++Time; } void Init(graph *g) { for(int i = 0;i < g->eNum;i++) { color[i] = 0; first[i] = 0; last[i] = 0; } is_DAG = true; Time = 0; } void DFS(graph *g) // 遍歷每一個點 { Init(g); // 別忘了初始化 for(int i = 0;i < g->vNum; i++) { if(color[i] == 0) //如果是白色, 表示沒訪問過 dfs(g,i); } } int main() { graph *g = new graph; g->vNum = 5; g->eNum = 3; // 初始化邊數和點數 Create(g); // 建圖 DFS(g); //遍歷圖 if(is_DAG) cout << "這個不是環" <<endl; else cout << " 是環 " << endl; for(int i = 0; i < 5; i++) cout << "點" << i << "開始與結束時間戳分別為:" << first[i] << " " << last[i] << endl; return 0; }