有向图的DFS遍历及判断是否有环(算法导论)

代码与10月22号已更正, 多谢 lbhqfwj 提出来

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

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/ygqwan/article/details/8866855
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞