拓扑排序算法主要由以下两步循环执行,直到不存在入度为 的顶点为止。

  1. 选择一个入度为 的顶点并将它输出;
  2. 删除从该顶点连出的所有边。
    循环结束,若输出的顶点数小于图中的顶点数,则表示该图中存在回路,也就是无法进行拓扑排序;否
    则输出的顶点序列就是一个拓扑序列。
    接下来,我们用一个例子来说明这个算法过程。对于如下的图,我们首先统计所有顶点的入度,并找出
    其中所有入度为零的顶点,发现只有 ,于是我们将 插入队列中。
    图中圆圈内的数字表示顶点的入度,圆圈下方的数字表示顶点编号,直线表示边,直线一端的箭头表示
    边的方向。图的下方是一个队列,用来在拓扑排序时储存所有未处理的入度为零的顶点。

基于邻接表的 C++ 示例代码如下:


基础代码

现在代码中已经给出了用来存储图的邻接表的声明和相关函数的实现。
接下来我们需要声明顶点数量 n 和边的数量 m 以及统计每个点入度的数组 indegree 。
在 main 函数上面写下

int n, m;
int indegree[MAX_N];

初始化操作以及输入 n和 m的值。
初始时所有点入度都是 0。
在 main 函数里面写下

init();
memset(indegree, 0, sizeof(indegree));
cin >> n >> m;

接下来输入 m 条边插入邻接表并增加该边终点的入度数量。
在 main 函数里面继续写下

for (int i = 0; i < m; i++)
{
int u, v;
cin >> u >> v;
insert(u, v);
indegree[v]++;
}

接下来实现 topo 函数,实现拓扑排序。拓扑排序的步骤如下:
1、首先我们找到图中入度为0 的点,将其入队。
我们在 main 函数前写下

void topo()
{
queue<int> q;
for (int i = 1; i <= n; i++)
{
if (indegree[i] == 0)
{
q.push(i);
}
}
}

拓扑排序的步骤:
2、每一次选取队首的点,将其输出并出队,随后删除所有以该点为起点的边,如果删边之后出现入度为的0点,则将这个点入队。
3、重复第二步直到队列为空。
我们先完成第2步的选取队首的点,输出并出队。
在 topo 函数里继续写下

while (!q.empty())
{
int now = q.front();
cout << now << endl;
q.pop();
}

拓扑排序的步骤:
2、每一次选取队首的点,将其输出并出队,随后删除所有以该点为起点的边,如果删边之后出现入度为0的点,则将这个点入队。
3、重复第二步直到队列为空。
接下来我们来完成第2 步的删边操作,边可以不用真删,只是改变该边终点的入度就可以了。
在 topo 函数里的 while 循环中继续写下

for (int i = p[now]; i != -1; i = E[i].next)
{
int v = E[i].v;
indegree[v]--;
}

拓扑排序的步骤:
2、每一次选取队首的点,将其输出并出队,随后删除所有以该点为起点的边,如果删边之后出现入度为0的点,则将这个点入队。
3、重复第二步直到队列为空。
接下来我们来完成第2步的入队操作,如果删边后出现了入度为0的点,我们需要把它加入队列。
在 topo 函数里的 while 循环中的 for 循环内继续写下

if (indegree[v] == 0)
{
q.push(v);
}

我们已经完成了 topo 函数,那么就可以在 main 函数里调用 topo 函数进行拓扑排序了。
在 main 函数里面写下

topo();

终于完成了,点击运行,输入下面的数据看看效果吧。

4 3
1 2
3 2
2 4

聪明的你一定学会了实现拓扑排序了

例题传送门:
排队
威虎山上的分配
ov.

【不带权图算法之拓扑排序】-C++的更多相关文章

  1. [BZOJ1565][NOI2009]植物大战僵尸-[网络流-最小割+最大点权闭合子图+拓扑排序]

    Description 传送门 Solution em本题知识点是用网络流求最大点权闭合子图. 闭合图定义:图中任何一个点u,若有边u->v,则v必定也在图中. 建图:运用最小割思想,将S向点权 ...

  2. 【noip模拟赛4】找啊找啊找BF 拓扑排序

    描述 sqybi上次找GF的工作十分不成功,于是依旧单身的他在光棍节前的某天突发奇想,要给自己找一个BF(这里指的是男性的好朋友……),这样既可以和人分享内心的压抑(路人甲:压抑还分享么……),也可以 ...

  3. CodeForces - 645D Robot Rapping Results Report(拓扑排序)

    While Farmer John rebuilds his farm in an unfamiliar portion of Bovinia, Bessie is out trying some a ...

  4. BZOJ3832[Poi2014]Rally——权值线段树+拓扑排序

    题目描述 An annual bicycle rally will soon begin in Byteburg. The bikers of Byteburg are natural long di ...

  5. 带权图的最短路径算法(Dijkstra)实现

    一,介绍 本文实现带权图的最短路径算法.给定图中一个顶点,求解该顶点到图中所有其他顶点的最短路径 以及 最短路径的长度.在决定写这篇文章之前,在网上找了很多关于Dijkstra算法实现,但大部分是不带 ...

  6. 拓扑排序&关键路径

    拓扑排序:AOV网 概念 example:选课问题:AOV网 顶点活动(Activity On Vertex)网是指用顶点表示活动,而用边集表示活动关系的有向图. 在这个例子中,课程为结点,而有向边表 ...

  7. 洛谷P1073 Tarjan + 拓扑排序 // 构造分层图

    https://www.luogu.org/problemnew/show/P1073 C国有 n n个大城市和 mm 条道路,每条道路连接这 nn个城市中的某两个城市.任意两个城市之间最多只有一条道 ...

  8. 算法:图(Graph)的遍历、最小生成树和拓扑排序

    背景 不同的数据结构有不同的用途,像:数组.链表.队列.栈多数是用来做为基本的工具使用,二叉树多用来作为已排序元素列表的存储,B 树用在存储中,本文介绍的 Graph 多数是为了解决现实问题(说到底, ...

  9. 【bzoj1093】[ZJOI2007]最大半连通子图 Tarjan+拓扑排序+dp

    题目描述 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:对于u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u的有向路径. ...

随机推荐

  1. 中资收购美新半导体,为何能通过CFIUS审查(其实是国内公司,技术水平国内领先,和国际仍有差距)

    日前,华灿光电发布公告称,旗下子公司和谐光电收购美国美新半导体终获得CFIUS审查通过.这是中资收购豪威科技.图芯科技等公司之后,再次从美国成功收购半导体企业.而且本次中资收购美新半导体还是在特朗普上 ...

  2. Java Web系列:Spring Boot 基础 Spring Security基本使用

    @OneToOne or @ManyToOne Caused by: org.hibernate.AnnotationException: @OneToOne or @ManyToOne on com ...

  3. shell产生随机数

    #!/bin/bash # 每次调用$RANDOM都会返回不同的随机整数. # 一般范围为: - (有符号的16-bit整数). MAXCOUNT= count= echo echo "$M ...

  4. 关于DDD领域驱动设计的理论知识收集汇总

    原文:关于DDD领域驱动设计的理论知识收集汇总 最近一直在学习领域驱动设计(DDD)的理论知识,从网上搜集了一些个人认为比较有价值的东西,贴出来和大家分享一下: 我一直觉得不要盲目相信权威,比如不能一 ...

  5. .NET重思(三)-数组列表与数组的区别,栈集合和队列结合的区别

    数组列表和数组十分相似,区别在于数组列表的容量是可以动态变化的,而数组的容量是固定的.数组即Array类,数组列表即ArrayList类,两者十分相似.不过,Array类在System命名空间下,Ar ...

  6. TWebBrowser控件与MSHTML库连接

    WebBrowser控件配置与IE的配置相同 方法一 使用Document属性得到 Document 层WebBrowser.Document:IDispatch //是IDispatch接口 Var ...

  7. jmeter报告分析工具

    一直以来做性能测试都是用jmeter和LR,当然还有一些自己写测试脚本,LR不用说,分析结果那个组件杠杠的!但是jmeter毕竟是开源的,所以分析查看结果不像LR那样自带图形神马的,虽然可以自己写脚本 ...

  8. python的实用函数

    >>> file=open('txt.txt','a') >>> print >> file,'hello,world' >>> fi ...

  9. 每日一问:到底为什么属性动画后 View 在新位置还能响应事件

    在 Android 开发中,我们难免会使用动画来处理各种各样的动画效果,以满足 UI 的高逼格设计.对于比较复杂的动画效果,我们通常会采用著名的开源库:lottie-android,或许你会对 lot ...

  10. Git 备忘录

    整理了一下工作中常用的 Git 操作,持续更新中...   merge单个文件 例如 B分支想要合并A分支的某个文件 首先,我们切换到B分支  git checkout branch B 之后,我们c ...