拓扑排序
拓扑序是有向无环图(DAG)的顶点排列:每条边 u→v 中 u 都在 v 前。存在环时没有拓扑序。
Kahn 算法
先统计所有入度,将入度为 0 的点入队;不断取点加入答案并删除其出边,新的入度 0 点继续入队。最终输出数量小于 n 即表示图有环。
queue<int> q; for(int i=1;i<=n;i++) if(indeg[i]==0) q.push(i);
vector<int> ord;
while(!q.empty()){int u=q.front();q.pop(); ord.push_back(u);
for(int v:g[u]) if(--indeg[v]==0) q.push(v);
}
if((int)ord.size()!=n) cout<<"cycle";
DFS 方法与应用
DFS 回溯时把点压入序列,最后反转;用 0/1/2 三色标记,遇到正在访问的点可判环。拓扑序常用于课程先修、任务调度、DAG 最短路与 DAG DP;多个入度 0 点的选择不同,合法序不一定唯一。
邻接表实现的时间为 O(n+m)、空间 O(n)。整理自 XOJ《拓扑排序》。