拓扑排序

· · 算法·理论

算法——拓扑排序

概念

在图论中,拓扑排序(Topological Sorting)是一个有向无环图(DAG)的所有顶点的线性序列。

序列必须满足这两个条件:

  1. 每个顶点出现且仅出现一次
  2. 若存在一条从顶点A到顶点B的路径,那么在序列中顶点A出现在顶点B的前面
  3. 只有有向无环图(DAG)才有拓扑序

例:

有向无环图G:

拓扑序为:

求解拓扑序

拓扑排序大多都用BFS求解

$step.2$ 从图中删除该顶点和所有以它为起点的所有有向边 (重复1和2,直到当前DAG图为空) (若在过程中当前图中不存在无前驱的顶点,则说明该DAG图中必然存在环) 图解: (以刚刚的有向无环图G为例) 找到入度为0的顶点$A$,并删除$A$以及以$A$为起点的所有有向边 ![](https://cdn.luogu.com.cn/upload/image_hosting/cbh12k0g.png) 将$A$点加入到序列中 ![](https://cdn.luogu.com.cn/upload/image_hosting/2ffk1rj0.png) 找到入度为0的顶点$B$,并删除$B$以及以$B$为起点的所有有向边 ![](https://cdn.luogu.com.cn/upload/image_hosting/7l4dvinx.png) 将$B$点加入到序列中 ![](https://cdn.luogu.com.cn/upload/image_hosting/wvmj0rnc.png) 找到入度为0的顶点$D$,并删除$D$以及以$D$为起点的所有有向边 ![](https://cdn.luogu.com.cn/upload/image_hosting/3xupt8db.png) 将$D$点加入到序列中 ![](https://cdn.luogu.com.cn/upload/image_hosting/ug1xoeei.png) 找到入度为0的顶点$C$,并删除$C$以及以$C$为起点的所有有向边 ![](https://cdn.luogu.com.cn/upload/image_hosting/5l1yp90c.png) 将$C$点加入到序列中 ![](https://cdn.luogu.com.cn/upload/image_hosting/fdh6lomt.png) 找到入度为0的顶点$E$,删除$E

E点加入到序列中

有向连通图G为空,输出序列

拓扑排序的应用场景

拓扑排序通常用来排序具有依赖关系的事物

例如用一个DAG图表示一个食物链,其中每个顶点表示食物链中的一个动物,用有向边表示会被吃的生物A和会吃A的生物B。在这个食物链中,任意两个动物不是具有确定的关系,就是没有关系,即满足生物学的要求,不会出现环。

献上拓扑排序模板

void Topological_Sorting()
{
    while (!q.empty())//队列非空(在执行函数前要把所有入度为0的顶点都push进来)
    {
        int u=q.front();//取出队首
        q.pop();
        for (int i=0;i<G[u].size();i++)
        {
            int v=G[u][i];//从u到v有一条有向边
            in[v]--;//v的入度-1
            if (!in[v])//若点v的入度为0则push到队列中
            {
                q.push(v);
            }
        }
    }
}