拓扑排序

拓扑排序

Fri Oct 04 2024
zzcoe
2 分钟

拓扑排序#

  • 首先统计所有节点的入度,将入度为零的节点加入s队列。
  • 节点从s队列出队,并加入拓扑排序数组l,将s子节点的入读减一,此时入度为零的加入s队列。
  • 重复上述步骤直到s队列为空
  • 时间复杂度O(E+V)
CPP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
void toposort() {//拓扑排序 
	
	for (int u=1;u<=n;u++){//统计入度 
		for (int i=head[u];~i;i=edge[i].next){
			to_head[edge[i].to]++;
		}
	}
	
	queue<int> s;
	for (int i=1;i<=n;i++){
		//入度为零进队 
		if (to_head[i]==0){
			s.push(i);
		}
	} 
	while (!s.empty()){
		int u=s.front();
		s.pop();
		//出队顺序就是拓扑顺序。 
		l.push_back(u);
		for (int v=head[u];~v;v=edge[v].next){
			if (--to_head[edge[v].to]==0){
				s.push(edge[v].to);
			}
		}
	}
	
	
	if (l.size()==n){
		for (int v:l){
			cout<<v<<endl;
		}
	}
}

求字典序最大/最小的拓扑排序#

将 Kahn 算法中的队列替换成最大堆/最小堆实现的[[STL#优先队列|优先队列]]即可,此时总的时间复杂度为O(E+VlogV)