圖的寬搜的一個經典應用就是求拓撲排序
拓撲排序是針對有向圖而言,無向圖沒有拓撲序列
比如這個有向圖
圖中的邊一共是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 }