图的宽搜的一个经典应用就是求拓扑排序
拓扑排序是针对有向图而言,无向图没有拓扑序列
比如这个有向图
图中的边一共是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 }