拓扑排序

拓扑排序

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;
}

posted on 2026-05-01 14:45  Sean2299  阅读(9)  评论(0)    收藏  举报

导航