代码与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;
}