7.有向图的拓扑序列 拓扑排序

 

 图的宽搜的一个经典应用就是求拓扑排序

拓扑排序是针对有向图而言,无向图没有拓扑序列

比如这个有向图

图中的边一共是1到2,2到3,1到3,对于每条边都是起点在终点的前面

 1 2 3就是一个拓扑序列,都是从前指向后的

并不是所有图都有拓扑序列

只要有一个环,无论如何都不可能有拓扑序列

 一个有向无环图,一定存在拓扑序列,但不唯一

有向无环图也称为拓扑图

 拓扑序列是指所有的边都是从前指向后的

因此所有入度为0的点(没有其他点指向这个点)都是可以作为起点的

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 100010;
 4 int h[N], e[N], ne[N], idx;
 5 int q[N], d[N];
 6 //q是手写队列,d存储入度
 7 int n, m;
 8 void add(int a, int b) {
 9     e[idx] = b;
10     ne[idx] = h[a];
11     h[a] = idx;
12     idx++;
13 }
14 bool topsort() {
15     int hh = 0, tt = -1;
16     for (int i = 1; i <= n; i++) {
17         if (d[i] == 0) { //把入度为0的点插进队列里面
18             q[++tt] = i;
19         }
20     }
21     while (hh <= tt) {
22         int t = q[hh++];
23         for (int i = h[t]; i != -1; i = ne[i]) {
24             int j = e[i];
25             d[j]--; //j的入度减一
26             if (d[j] == 0) {
27                 q[++tt] = j;
28             }
29         }
30     }
31     return tt == n - 1; //如果进入了n个点,说明是拓扑序列
32 }
33 int main() {
34     memset(h, -1, sizeof(h));
35     cin >> n >> m;
36     while (m--) {
37         int a, b;
38         cin >> a >> b;
39         add(a, b);
40         d[b]++; //b的入度++
41     }
42     if (topsort()) {
43         for (int i = 0; i < n; i++) {
44             cout << q[i] << " ";
45         }
46         cout << endl;
47     } else {
48         cout << -1 << endl;
49     }
50     return 0;
51 }
原文地址:https://www.cnblogs.com/fx1998/p/13324931.html