拓扑排序
拓扑排序
1)解决依赖关系的问题
例如:一个人需要上n门课,但是上a课之前要先上b课,上b课之前要先上c课,求上课的顺序。可以将上述关系抽象为一个有向图,c -> b, b -> a,并将每一个结点的入边数量用一个入度表存起来,a:1,b:1,c:0 入度为零的就是可以直接上的课,先输出c,然后以c为开始结点的边的结束结点的入度都减少一,b:0;输出b;然后同理a:0;输出a
2)代码实现:
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
const int MAXN = 2010;
vector<int>indegree(MAXN,0);
vector<int>degree(MAXN,0);
vector<vector<int>>graph;
void prebuild(int n){
indegree = degree;
graph.clear();
for(int i = 0;i<n;i++){
graph.push_back(vector<int>());
}
}
void build(vector<vector<int>>&edges){
for(const auto &edge : edges){
graph[edge[1]].push_back(edge[0]);
indegree[edge[0]]++;
}
}
vector<int> findOrder(int n){
//用一个队列记录入度为0的结点
vector<int>que(n);
int l = 0;
int r = 0;
for(int i = 0;i<n;i++){
if(indegree[i] == 0){
que[r++] = i;
}
}
//记录数量
int cnt = 0;
while(l<r){
int cur = que[l++];
cnt++;
for(int next : graph[cur]){
if(--indegree[next] == 0){
que[r++] = next;
}
}
}
return cnt == n ? que:vector<int>();
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int n = 4;
vector<vector<int>>edges = {
{1,0},
{2,0},
{3,1},
{3,2}
};
prebuild(n);
build(edges);
vector<int>ans = findOrder(n);
for(int t : ans){
cout << t << " ";
}
cout << endl;
return 0;
}
浙公网安备 33010602011771号