[笔记]拓扑排序

对于一个有向无环图(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\)的节点,说明一定存在环。

posted @ 2024-05-08 23:07  Sinktank  阅读(40)  评论(0编辑  收藏  举报
★CLICK FOR MORE INFO★ TOP-BOTTOM-THEME
Enable/Disable Transition
Copyright © 2023 ~ 2024 Sinktank - 1328312655@qq.com
Illustration from 稲葉曇『リレイアウター/Relayouter/中继输出者』,by ぬくぬくにぎりめし.