演算法分析與設計期中測試——拓撲序[Special judge]
阿新 • • 發佈:2018-11-03
在圖論中,拓撲序(Topological Sorting)是一個有向無環圖(DAG, Directed Acyclic Graph)的所有頂點的線性序列. 且該序列必須滿足下面兩個條件:
- 每個頂點出現且只出現一次.
- 若存在一條從頂點 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;
}
};