Loading

拓扑排序

Topological sort

leetcode 210

问题描述

首先判断有向图里有无环,有环则没有拓扑排序
官方定义:

a topological sort or topological ordering of a directed graph is a linear ordering of its vertices such that for every directed edge uv from vertex u to vertex v, u comes before v in the ordering.

即若有一条u指向v的有向边,则序列里u必须在v前面

BFS

不断寻找入度为0的点,加入到序列中,接着减少其指向节点的入度

class Solution {
public:
    vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
        int n=numCourses;
        vector<int> degrees(n,0);
        vector<vector<int>> g(n);
        vector<int> ans;
        for(auto edge : prerequisites)
        {
            int prev=edge[1];
            int next=edge[0];
            g[prev].push_back(next);
            ++degrees[next];
        }
        for(int i=0;i<n;++i)
        {
            int j;
            for(j=0;j<n;++j)
                if(!degrees[j])
                    break;
            if(j==n)
                return {};
            ans.push_back(j);
            --degrees[j];
            for(auto next : g[j])
                --degrees[next];
        }
        return ans;
    }
};

DFS

跟DFS搜索类似,只不过在开始遍历边之前,设vis[cur]=-1,表示当前节点正在遍历。
若发现相邻节点vis[j]==-1,则说明回到了路径前面的点,产生了环。
在遍历后将当前节点加入到序列中
由于最先完成DFS的一定是出度最小的点,因此将加入的序列反转后即是拓扑排序

class Solution {
public:
    vector<int> ans;
    vector<int> vis;
    vector<vector<int>> g;
    bool dfs(vector<int>& vis,vector<vector<int>>& g,int cur){
        vis[cur]=-1;
        for(auto nxt : g[cur])
        {
            if(vis[nxt]==-1)
                return false;//form a cycle
            if(!vis[nxt]&&!dfs(vis,g,nxt))
                return false;
        }
        vis[cur]=1;
        ans.push_back(cur);
        return true;
    }
    vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
        int n=numCourses;
        vector<int> vis(n,0);
        vector<vector<int>> g(n);
        for(auto edge : prerequisites)
        {
            int prev=edge[1];
            int next=edge[0];
            g[prev].push_back(next);
        }
        for(int i=0;i<n;++i){
            if(!vis[i]&&!dfs(vis,g,i)){
                return {};
            }
        }
        reverse(ans.begin(),ans.end());
        return ans;
    }
};
posted @ 2021-11-18 22:45  traver  阅读(38)  评论(0编辑  收藏  举报