假设输入的图是有向无环图,则一定有一个点为源点,入度为0。通过删除源点及它的出度会得到新的入度为0的点。重复此过程,删除点的顺序就是拓扑排序的顺序。代码如下:
class Solution { public: vector<int> topologicalSort(int n, vector<pair<int, int>>& edges) { vector<vector<int>> graph = makeGraph(edges, n); vector<int> indegree = computeIndegree(edges, n); queue<int> zeroIndegree; for (int i = 0; i < n; i++) if (indegree[i] == 0) zeroIndegree.push(i); vector<int> result; for (int i = 0; i < n; i++) { if (zeroIndegree.empty()) return{}; int front = zeroIndegree.front(); zeroIndegree.pop(); result.push_back(front); for (auto neighbors : graph[front]) if (!--indegree[neighbors]) zeroIndegree.push(neighbors); } return result; } vector<vector<int>> makeGraph(vector<pair<int, int>>& edges, int n) { vector<vector<int>> graph(n); for (auto neighbors : edges) graph[neighbors.first].push_back(neighbors.second); return graph; } vector<int> computeIndegree(vector<pair<int, int>>& edges, int n) { vector<int> indegree(n, 0); for (pair<int, int> neighbors : edges) indegree[neighbors.second]++; return indegree; } };
任选一个起点进行DFS,每一个节点记录pre值和post值(分别为第一次访问该节点的顺序和子节点访问完后最后一次访问该节点的时间),按post值进行从大到小排序,得到的结果就是拓扑排序的结果,代码如下:
class Solution {
public:
vector<int> topologicalSort(int n, vector<pair<int, int>>& edges) {
vector<int> result;
DFS(n, edges,result);
return result;
}
void explore(int n, vector<pair<int, int>>& edges, int j,int * visit, vector<int> & result) {
visit[j] = 1;
for (int i = 0; i < edges.size(); ++i) {
if (edges[i].first == j && visit[edges[i].second] == 0) {
explore(n, edges, edges[i].second, visit, result);
}
}
vector<int>::iterator iter = result.begin();
result.insert(iter, j);
return;
}
void DFS(int n, vector<pair<int, int>>& edges, vector<int> & result) {
int * visit = new int[n];
for (int i = 0; i < n; ++i) {
visit[i] = 0;
}
for (int i = 0; i < n; ++i) {
if (visit[i] == 0) {
explore(n, edges, i, visit,result);
}
}
}
};