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;
}

有向图是否存在环

  只需要将上述代码的无向图的构造过程改成有向图即可

猜你喜欢

转载自www.cnblogs.com/dotdashdotdash/p/11863579.html