進行深度優先搜索的時候,如果當前訪問的點是已經被訪問過的節點的話,說明出現了逆邊。因此有環,無法完成拓撲排序。
如果可以完成拓撲排序,檢測點序列就是一個合法的拓撲排序!
#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
*/