【C++】拓撲排序 (Topological Sort)

拓撲排序:對有向無環圖 (DAG) 的節點進行排序,使得對於任何 u 到 v 的有向邊,u 都會出現在 v 之前。

常見考題:課程先修安排、任務的先後順序。

寫法

計算每個節點的入度 (指向該節點的邊數),將入度為 0 的節點加入佇列中。從佇列中取出節點,並將相鄰節點的入度減 1,重複以上步驟,直到佇列為空。

例題

ZeroJudge:f167. m4a1-社團 Club (本題 100% 拓撲排序)

#include <iostream>
#include <queue>
#include <vector>
using namespace std;

int main() {
    int n, m, a, b; // n 為節點數,m 為邊數
    cin >> n >> m;
    vector<vector<int>> g(n); // 儲存圖的鄰接表
    vector<int> indegree(n, 0); // 儲存每個節點的入度
    while (m--) {
        cin >> a >> b;
        a--, b--; // 將節點編號轉成 zero-based
        g[a].push_back(b);
        indegree[b]++;
    }
    queue<int> q;
    vector<int> ans;
    for (int i = 0; i < n; i++) {
        if (indegree[i] == 0) q.push(i);
    }
    while (!q.empty()) {
        int now = q.front();
        ans.push_back(now + 1); // 將結果轉換回 1-based
        q.pop();
        for (int i : g[now]) {
            if (--indegree[i] == 0) q.push(i);
        }
    }
    if (ans.size() != n) {
        cout << "NO\n";
    } else {
        cout << "YES\n";
        for (int i : ans) {
            cout << i << '\n';
        }
    }
}
發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *