1. 程式人生 > >演算法分析與設計期中測試——拓撲序[Special judge]

演算法分析與設計期中測試——拓撲序[Special judge]

在圖論中,拓撲序(Topological Sorting)是一個有向無環圖(DAG, Directed Acyclic Graph)的所有頂點的線性序列. 且該序列必須滿足下面兩個條件:

  1. 每個頂點出現且只出現一次.
  2. 若存在一條從頂點 A 到頂點 B 的路徑,那麼在序列中頂點 A 出現在頂點 B 的前面.

對於一個含有n個節點的有向無環圖(節點編號0到n-1),輸出它的一個拓撲序.

圖的節點數和邊數均不多於100000,保證輸入的圖是一個無環圖.

請為下面的Solution類實現解決上述問題的topologicalSort函式,函式引數中n為圖的節點數,edges是邊集,edges[i]表示第i條邊從edges[i].first指向edges[i].second. 函式返回值為有向圖的一個拓撲序. 有向圖有多個拓撲序時,輸出任意一個即可.

class Solution {
public:
vector topologicalSort(int n, vector< pair < int, int>>& edges) {
}
};

例1:
n = 3,edges = {(0, 1), (0, 2)},函式應返回{0, 1, 2}或者{0, 2, 1}.

例2:
n = 4,edges = {(0, 1), (0, 2), (1, 2), (3, 0)},函式應返回{3, 0, 1, 2}.

注意:你只需要提交Solution類的程式碼,你在本地可以編寫main函式測試程式,但不需要提交main函式的程式碼. 注意不要修改類和函式的名稱.

拓撲排序問題,簡單的演算法就是每次輸出入度為0的點,從圖中刪除,然後繼續找入度為0的點。要注意優化的地方就是改用一個鄰接表來儲存邊,這樣在就不用每次都去遍歷所有的邊,避免超時。


class Solution {
public:
    vector<int> topologicalSort(int n, vector<pair<int, int>>& edges) {
    //用一個佇列來儲存所有入度為0的點
        queue<int> DegreeZero;
        //用一個vector來儲存所有的入度
        vector
<int>
indegree(n); vector<vector<int>> myedges(n); vector<int> result; for (int i = 0; i < n; i++) { indegree[i] = 0; } for (int i = 0; i < edges.size(); i++) { int toV = edges[i].second; indegree[toV]++; myedges[edges[i].first].push_back(edges[i].second); } for (int i = 0; i < n; i++) { if (indegree[i] == 0) { DegreeZero.push(i); } } while (!DegreeZero.empty()) { int temp = DegreeZero.front(); result.push_back(temp); DegreeZero.pop(); for (int i = 0; i < myedges[temp].size(); i++) { indegree[myedges[temp][i]]--; if (indegree[myedges[temp][i]] == 0) { DegreeZero.push(myedges[temp][i]); } } } return result; } };