利用_DFS_來判斷無向圖是否存在環的條件思路,我看一次_DFS_是否能訪問到之前訪問到的節點,如果能夠訪問到,就說明圖存在環,那么關鍵問題就是判斷是一次DFS?,追根到_DFS_算法的實現細節,發現我們設置_visited_數組時只有設置0和1兩個狀態,那么就可以改進以下之前的_DFS_算法,將_visited_各個狀態表示成如下狀態:
- 0: 沒有被訪問過
- 1: 剛剛訪問,但是鄰接點沒有被全部訪問完
- 2: 所有的鄰接點都被訪問完了,這里就可以判定_DFS_一定退出了
關鍵問題就解決了,看下面的簡易的測試代碼,同時也運用到了並查集的數據結構:
#include<iostream>
#include<stdlib.h>
#define maxsize 100
#define INF 0x3f3f3f3f
using namespace std;
int g[maxsize][maxsize];
int vexnum, arcnum;
int visited[maxsize], father[maxsize];
int flag = 0;
void InitGraph(){
cout << "輸入頂點數和邊數: ";
cin >> vexnum >> arcnum;
for(int i = 0; i < vexnum; i++){
//初始化visited數組和father數組
visited[i] = 0;
father[i] = -1;
}
for(int i = 0; i < arcnum; i++){
int s, e;
cout << "請輸入第" << i << "條邊的起點和終點: ";
cin >> s >> e;
g[s][e] = 1;
g[e][s] = 1;
}
}
void DFS(int v){
visited[v] = 1;
for(int i = 0; i < vexnum; i++){
if(i != v && g[v][i] != INF){
//這里的判斷是重點!!一次DFS且該節點不是從上一個節點過來的
if(visited[i] == 1 && father[v] != i){
flag = 1;
cout << "圖存在環: ";
int tmp = v;
while(tmp != i){
cout << tmp << " ";
tmp = father[tmp];
}
cout << tmp << endl;
}else{
if(visited[i] == 0){
father[i] = v;
DFS(i);
}
}
}
}
visited[v] = 2;
}
int main(){
InitGraph();
for(int i = 0; i < vexnum; i++){
if(!visited[i])
DFS(i);
}
if(!flag)
cout << "圖不存在環!" << endl;
return 0;
}
有向圖是否存在環
只需要將上述代碼的無向圖的構造過程改成有向圖即可