[笔记]拓扑排序
对于一个有向无环图(DAG)的顶点按顺序排成一个序列的过程,就是拓扑排序(Topological Sort)。
具体来说,这个序列必须满足:
- 每个顶点正好出现\(1\)次。
- 如果图上存在一条\(A\to B\)的路径,那么\(A\)一定在\(B\)之前。
注意:拓扑排序结果可能不唯一。
注意与DFS序、BFS序进行区分,DFS序和BFS序倒过来一定是拓扑序,但拓扑序反过来不一定是DFS序或BFS序。
具体做法就是每次在图中寻找\(1\)个入度为\(0\)的节点,将其加入序列,并删除该点和其所有出边。
模板题:B3644 【模板】拓扑排序 / 家谱树。
此处用BFS实现。邻接表\(G\)存图,同时用\(deg\)记录下每个点的入度。
#include<bits/stdc++.h>
using namespace std;
int n,deg[110];
vector<int> G[110];
queue<int> q;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
int u;
while(cin>>u){
if(u==0) break;
G[i].push_back(u);
deg[u]++;
}
}
for(int i=1;i<=n;i++){
if(deg[i]==0){
q.push(i);
}
}
while(!q.empty()){
int t=q.front();
q.pop();
cout<<t<<" ";
for(auto i:G[t]){
deg[i]--;
if(!deg[i]){
q.push(i);
}
}
}
return 0;
}
时间复杂度\(O(e+v)\)。
拓扑排序仅适用于有向无环图(DAG),而我们可以利用拓扑排序来判断有向图是否有环。只要中途找不到入度为\(0\)的节点,说明一定存在环。