拓扑排序(topo_sort)

本文深入讲解了拓扑排序的基本概念及应用,介绍了如何利用有向无环图(DAG)来表示活动间的依赖关系,并通过具体算法实现展示了拓扑排序在解决实际问题中的应用。

拓扑排序

预备知识

​   一个较大的工程往往被划分成许多子工程,我们把这些子工程称作活动(activity)。在整个工程中,有些子工程(活动)必须在其它有关子工程完成之后才能开始,也就是说,一个子工程的开始是以它的所有前序子工程的结束为先决条件的,但有些子工程没有先决条件,可以安排在任何时间开始。为了形象地反映出整个工程中各个子工程(活动)之间的先后关系,可用一个有向图来表示,图中的顶点代表活动(子工程),图中的有向边代表活动的先后关系,即有向边的起点的活动是终点活动的前序活动,只有当起点活动完成之后,其终点活动才能进行。通常,我们把这种顶点表示活动、边表示活动间先后关系的有向图称做顶点活动网(Activity On Vertex network),简称AOV网。
  一个AOV网应该是一个有向无环图,即不应该带有回路,因为若带有回路,则回路上的所有活动都无法进行。这种情况若在程序中出现,则称为死锁或死循环,是必须避免的。
  在AOV网中,若不存在回路,则所有活动可排列成一个线性序列,使得每个活动的所有前驱活动都排在该活动的前面,我们把此序列叫做拓扑序列(Topological order),由AOV网构造拓扑序列的过程叫做拓扑排序(Topological sort)。AOV网的拓扑序列不是唯一的,满足上述定义的任一线性序列都称作它的拓扑序列。
  由AOV网构造出拓扑序列的实际意义是:如果按照拓扑序列中的顶点次序,在开始每一项活动时,能够保证它的所有前驱活动都已完成,从而使整个工程顺序进行,不会出现冲突的情况。

定义

  对一个有向无环图(Directed Acyclic Graph简称DAG) 进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边<u,v>∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。

  

#641. 拓扑排序

在这里插入图片描述

小数在前大数在后——维护一个入度为0的小顶堆顶点集合
#include <iostream>
#include <cstdio>
#include <queue>
#include <vector>

using namespace std;

#define N 2000
#define M 400000

int head[N + 5], edg[M + 5], nxt[M + 5], tot;
int in_degree[N + 5];

void add(int s, int e) {
   
   
    ++in_degree[e];
    ++tot;
    edg[tot] = e;
    nxt[tot] = head[s];
    head[s] = tot;
    return ;
}

priority_queue<int, vector<int>, greater<int> > que;

int main() {
   
   
    int n, m;
    cin >> n >> m;
    for (int i = 1, s, e; i <= m; ++i) {
   
   
        cin >> s >> e;
        add(s, e);
    }
    for (int i = 1; i <= n; ++i) {
   
   
        if (in_degree[i] == 0)  que.push(i);
    }
    while (!que.empty()) {
   
   
        int t = que.top();
        que.pop();
        cout << t;
        for (int i = head[t]; i; i = nxt[i]) {
   
   
            --in_degree[edg[i]];
            if (in_degree[edg[i]] == 0)  que.push(edg[i]);
        }
        if (!que.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值