拓扑序列

拓扑序列

一、什么是拓扑排序在图论中,拓扑排序(Topological Sorting)是一个有向无环图(DAG, Directed Acyclic Graph)的所有顶点的线性序列。且该序列必须满足下面两个条件:

每个顶点出现且只出现一次。若存在一条从顶点 A 到顶点 B 的路径,那么在序列中顶点 A 出现在顶点 B 的前面。有向无环图(DAG)才有拓扑排序,非DAG图没有拓扑排序一说。

例如,下面这个图:

它是一个 DAG 图,那么如何写出它的拓扑排序呢?这里说一种比较常用的方法:

1:从 DAG 图中选择一个 没有前驱(即入度为0)的顶点并输出。 2:从图中删除该顶点和所有以它为起点的有向边。 3:重复 1 和 2 直到当前的 DAG 图为空或当前图中不存在无前驱的顶点为止。后一种情况说明有向图中必然存在环。

于是,得到拓扑排序后的结果是 { 1, 2, 4, 3, 5 }。

通常,一个有向无环图可以有一个或多个拓扑排序序列。

二、拓扑排序的应用拓扑排序通常用来“排序”具有依赖关系的任务。

比如,如果用一个DAG图来表示一个工程,其中每个顶点表示工程中的一个任务,用有向边表示在做任务 B 之前必须先完成任务 A。故在这个工程中,任意两个任务要么具有确定的先后关系,要么是没有关系,绝对不存在互相矛盾的关系(即环路)。

三 题目:

给定一个n个点m条边的有向图,图中可能存在重边和自环。

请输出任意一个该有向图的拓扑序列,如果拓扑序列不存在,则输出-1。

若一个由图中所有点构成的序列A满足:对于图中的每条边(x, y),x在A中都出现在y之前,则称A是该图的一个拓扑序列。

输入格式

第一行包含两个整数n和m

接下来m行,每行包含两个整数x和y,表示存在一条从点x到点y的有向边(x, y)。

输出格式

共一行,如果存在拓扑序列,则输出拓扑序列。

否则输出-1。

数据范围

1≤n,m≤1051≤n,m≤105

输入样例:

3 3

1 2

2 3

1 3

输出样例:

1 2 3

############################################

1 #include

2 using namespace std;

3

4 const int N = 1e5+10;

5 vector h(N,-1), e(N,-1), ne(N,0);

6 int idx;

7 int q[N],hh = 0, tt = -1;//模拟队列

8 int d[N];//入度

9 int n, m;

10

11 void add(int a, int b){

12 e[idx] = b;

13 ne[idx] = h[a];

14 h[a] = idx ++;

15 }

16

17 bool topsort(){

18 for(int i = 1;i <= n;++i)

19 if(d[i] == 0) q[++tt] = i;

20 while(hh <= tt){

21 int t = q[hh++];

22 for(int i = h[t];i != -1;i = ne[i]){

23 int tmp = e[i];

24 -- d[tmp];

25 if(d[tmp] == 0) q[++tt] = tmp;

26 }

27 }

28 return tt == n-1;

29 }

30

31 int main(){

32 cin >> n >> m;

33 for(int i = 0;i < m;++i){

34 int a, b;

35 cin >> a >> b;

36 add(a, b);

37 d[b] ++;

38 }

39 if(topsort()){

40 for(int i = 0;i < n;++i)cout << q[i] << " ";

41 }else cout << -1 << endl;

42 return 0;

43 }

View Code

相关推荐

魔兽世界7.3飞行解锁
365bet官方网址

魔兽世界7.3飞行解锁

📅 07-09 👁️ 4041
手机桌面软件排行榜
365bet欧洲版官网

手机桌面软件排行榜

📅 07-10 👁️ 6359
重庆卖婬哪个村多
365bet官方网址

重庆卖婬哪个村多

📅 07-03 👁️ 666