进行深度优先搜索的时候,如果当前访问的点是已经被访问过的节点的话,说明出现了逆边。因此有环,无法完成拓扑排序。
如果可以完成拓扑排序,检测点序列就是一个合法的拓扑排序!
#include <iostream>
#include <vector>
using namespace std;
class Solution {
vector<vector<int> > graph;
vector<int> visited;
vector<int> path;
void dispGraph()
{
for (int i = 0; i < graph.size(); ++i) {
cout << i << ": ";
for (int j = 0; j < graph[i].size(); ++j) {
cout << graph[i][j] << " ";
}
cout << endl;
}
}
bool dfs(int s)
{
visited[s] = 1;
for (int i = 0; i < graph[s].size(); ++i) {
int nextv = graph[s][i];
if (visited[nextv] == 0) {
if (dfs(nextv) == false)
return false;
}
else if (visited[nextv] == 1)
return false;
}
visited[s] = 2;
path.push_back(s); // 将检测点加入到path中
return true;
}
public:
bool canFinish(int numCourses, vector<pair<int, int> > &prerequisites)
{
graph = vector<vector<int> >(numCourses, vector<int>());
for (vector<pair<int, int> >::iterator it = prerequisites.begin(); it != prerequisites.end(); ++it) {
graph[it->first].push_back(it->second);
}
// dispGraph();
visited = vector<int>(numCourses, 0);
for (int i = 0; i < numCourses; ++i) {
if (visited[i] == 0 && dfs(i) == false) {
return false;
}
}
cout << "path is : ";
for (int i = 0; i < path.size(); ++i)
cout << path[i] << " ";
cout << endl;
return true;
}
};
int main()
{
int numCourse, e;
cin >> numCourse >> e;
vector<pair<int, int> > prerequisites;
for (int i = 0; i < e; ++i) {
int next, pre;
cin >> next >> pre;
prerequisites.push_back(make_pair(next, pre));
}
cout << Solution().canFinish(numCourse, prerequisites) << endl;
return 0;
}
/* 5 6 0 2 2 3 3 4 0 1 1 2 1 3 output: path is: 4 3 2 1 0 1 5 7 0 2 2 3 3 4 0 1 1 2 1 3 4 3 output: 0 */