有向无环图的拓扑排序

时间:2023-02-02 15:02:12

有向无环图的拓扑排序

有向无环图(DAG),指不存在环的有向图。

点的入度,指以这个点为结束点的边数。

点的出度,指以这个点为出发点的边数。

拓扑序就是对于节点的一个排列使得若(u,v)∈E,那么u在排列中出现的位置一定在v前面。

而拓扑排序,则是一个用于求解拓扑序的方法(只需要求出一组解)

根据以上描述,我们可以发现我们只要每次找到入度为0的节点,把该节点输出,并删除该节点和这个节点所有的后继,就可以的到一个图的拓扑排序了。

有向无环图的拓扑排序

像这张图,一种合法的拓扑排序就是1 2 4 3 5。

在这里使用队列来实现拓扑排序。

代码:

 

有向无环图的拓扑排序有向无环图的拓扑排序
 1 #include<queue>
2 #include<cstdio>
3 #include<algorithm>
4 #define N 42000
5 using namespace std;
6 queue<int>p;
7 int next[N],num,to[N],head[N],n,m,a,b,r[N],u,pre[N],ans[N],sum;
8 void add(int false_from,int false_to){
9 next[++num]=head[false_from];
10 to[num]=false_to;
11 head[false_from]=num;
12 }
13 int main(){
14 scanf("%d%d",&n,&m);
15 for(int i=1;i<=m;++i){
16 scanf("%d%d",&a,&b);
17 add(a,b);
18 r[b]++;
19 }
20 for(int i=1;i<=n;++i)
21 if(!r[i])
22 p.push(i);
23 while(!p.empty()){
24 num=0;
25 u=p.front();
26 p.pop();
27 ans[++sum]=u;
28 for(int i=head[u];i;i=next[i]){
29 r[to[i]]--;
30 if(!r[to[i]])
31 pre[++num]=to[i];
32 }
33 sort(pre+1,pre+num+1);
34 for(int i=1;i<=num;++i)
35 p.push(pre[i]);
36 }
37 for(int i=1;i<=sum;++i)
38 printf("%d ",ans[i]);
39 return 0;
40 }
View Code