[编程笔记]-Topo_Sort拓扑排序

概念

拓扑排序,就是对图中的点进行排序。

排序方式如下:

对于每一个点,它指向的点都排在它后面,指向它的点都排在它前面。

所以,图只能是有向图,还得是有向无环图

实现

记录每一个点的入度,把入度为0的点加入队列,然后BFS一遍,每遍历一个点,就把它“删掉”,使其所有相邻点入度减一,然后再把入度为0的点加入队列。

无须用到vis数组的证明:如果重复遇到同一个点,则说明指向这个点的边不止一条,但是只有当入度为0时才会把这个点加入队列,所以这个点只会被遍历一次。

代码

由于这是个算法,所以模板不是很固定,所以就直接上模板题吧。

例题

AcWing848-有向图的拓扑排序

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include<bits/stdc++.h>
using namespace std;

const int N=1e5+5;

int n,m;
int x,y;
int dg[N];
vector<int> vec;

int idk;
int hd[N],to[N],ne[N];

void merge(int a,int b){
to[++idk]=b;
ne[idk]=hd[a];
hd[a]=idk;
dg[b]++;
}

bool topo(){
int fns=0;
queue<int> q;
for(int i=1;i<=n;i++){
if(dg[i]==0)q.push(i);
}
while(!q.empty()){
int now=q.front();q.pop();
vec.push_back(now);
fns++;
for(int i=hd[now];i;i=ne[i]){
dg[to[i]]--;
if(dg[to[i]]==0)q.push(to[i]);
}
}
return fns==n;
}

int main(){
cin>>n>>m;
while(m--){
cin>>x>>y;
merge(x,y);
}
if(topo()){
for(int i=0;i<vec.size();i++)cout<<vec[i]<<" ";
}
else{
cout<<-1;
}
return 0;
}

完结撒花o( ̄︶ ̄)o


[编程笔记]-Topo_Sort拓扑排序
http://githarlem.github.io/2024/08/03/Topo-Sort/
作者
Harlem
发布于
2024年8月3日
更新于
2024年8月3日
许可协议