拓扑序列
一、算法原理
1. Kahn算法(基于入度的贪心算法)
- 核心思想:不断删除入度为0的顶点,直到图为空或存在环。
- 步骤:
- 统计每个顶点的入度。
- 将入度为0的顶点加入队列。
- 依次取出队列中的顶点,将其邻接顶点入度减1,若减至0则入队。
- 若结果顶点数 ≠ 总顶点数,说明存在环。
2. 基于DFS的后序遍历法
- 核心思想:通过深度优先搜索遍历图,按完成时间的逆序输出顶点。
- 步骤:
- 对未访问顶点进行DFS。
- 递归访问邻接顶点,完成后将当前顶点压入栈。
- 最终栈中元素即为拓扑序列。
- 若DFS中发现已访问但未完成的顶点,说明存在环。
二、C++代码实现
方法1:Kahn算法
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
vector<int> topologicalSortKahn(int n, vector<vector<int>>& edges) {
vector<vector<int>> adj(n);
vector<int> inDegree(n, 0);
for (auto& e : edges) {
adj[e[0]].push_back(e[1]);
inDegree[e[1]]++;
}
queue<int> q;
for (int i = 0; i < n; ++i) {
if (inDegree[i] == 0) q.push(i);
}
vector<int> res;
while (!q.empty()) {
int u = q.front();
q.pop();
res.push_back(u);
for (int v : adj[u]) {
if (--inDegree[v] == 0) {
q.push(v);
}
}
}
if (res.size() != n) {
cout << "图中有环!" << endl;
return {
};
}
return res;
}
方法2:基于DFS的算法
#include <stack>
#include <vector>
#include <iostream>
using namespace std;
bool dfs(int u, vector<int>& visited, vector<vector<int>>& adj, stack<int>& stk) {
if (visited[u] == 1) return false;
if (visited[u] == 2) return true;
visited[u] = 1;
for (int v : adj[u]) {
if (!dfs(v, visited, adj, stk)