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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM