DFS判斷圖是否有環


  利用_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;
}

有向圖是否存在環

  只需要將上述代碼的無向圖的構造過程改成有向圖即可


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM