拓扑排序(Topological Sorting)

拓扑排序(Topological Sorting)
拓扑排序(Topological Sorting)是一个有向无环图(DAG, Directed Acyclic Graph)的所有顶点的线性序列。DAG的判定
拓扑排序的时间复杂度为O ( V + E ),因为DFS的时间复杂度度为O ( V + E )
该序列必须满足下面两个条件:

  • 每个顶点出现且只出现一次。
  • 若存在一条从顶点 A 到顶点 B 的路径,那么在序列中顶点 A 出现在顶点 B 的前面。
    有向无环图(DAG)才有拓扑排序,非DAG图没有拓扑排序一说。
    例如,下面这个图:


    拓扑排序(Topological Sorting)_第1张图片

它是一个 DAG 图,那么如何写出它的拓扑排序呢?这里说一种比较常用的方法:

  • 1.从 DAG 图中选择一个 没有前驱(即入度为0)的顶点并输出。
  • 2.从图中删除该顶点和所有以它为起点的有向边。

重复 1 和 2 直到当前的 DAG 图为空或当前图中不存在无前驱的顶点为止。后一种情况说明有向图中必然存在环。


拓扑排序(Topological Sorting)_第2张图片

于是,得到拓扑排序后的结果是 { 1, 2, 4, 3, 5 }。

通常,一个有向无环图可以有一个或多个拓扑排序序列。

#include 
#include
#include
using namespace std;
const int MAXN=100010;
vector graph[MAXN];
int in[MAXN];
void topoSort(int n)
{
    vector zero;//0入度点
    vector result;//排序结果
    for(int i=1;i<=n;i++)
    {
        if(in[i]==0) zero.push_back(i);
    }
    while(!zero.empty())
    {
        int curr=zero.back();
        zero.pop_back();
        result.push_back(curr);
        int len=graph[curr].size();
        for(int i=0;i

还有一种直观的方法是利用DFS,容易知道拓扑排序的序列为所有顶点的逆后续排列(ReversePostOrder)

#include 
#include
#include
#include
using namespace std;
const int MAXN=100010;
vector graph[MAXN];
stack result;//排序结果
int vis[MAXN];
bool DFS(int u)
{
    if(vis[u]==2) return true;
    vis[u]=2;
    int len=graph[u].size();
    for(int i=0;i

你可能感兴趣的:(拓扑排序(Topological Sorting))