【不带权图算法之拓扑排序】-C++
拓扑排序算法主要由以下两步循环执行,直到不存在入度为 的顶点为止。
- 选择一个入度为 的顶点并将它输出;
- 删除从该顶点连出的所有边。
循环结束,若输出的顶点数小于图中的顶点数,则表示该图中存在回路,也就是无法进行拓扑排序;否
则输出的顶点序列就是一个拓扑序列。
接下来,我们用一个例子来说明这个算法过程。对于如下的图,我们首先统计所有顶点的入度,并找出
其中所有入度为零的顶点,发现只有 ,于是我们将 插入队列中。
图中圆圈内的数字表示顶点的入度,圆圈下方的数字表示顶点编号,直线表示边,直线一端的箭头表示
边的方向。图的下方是一个队列,用来在拓扑排序时储存所有未处理的入度为零的顶点。
基于邻接表的 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
聪明的你一定学会了实现拓扑排序了
【不带权图算法之拓扑排序】-C++的更多相关文章
- [BZOJ1565][NOI2009]植物大战僵尸-[网络流-最小割+最大点权闭合子图+拓扑排序]
Description 传送门 Solution em本题知识点是用网络流求最大点权闭合子图. 闭合图定义:图中任何一个点u,若有边u->v,则v必定也在图中. 建图:运用最小割思想,将S向点权 ...
- 【noip模拟赛4】找啊找啊找BF 拓扑排序
描述 sqybi上次找GF的工作十分不成功,于是依旧单身的他在光棍节前的某天突发奇想,要给自己找一个BF(这里指的是男性的好朋友……),这样既可以和人分享内心的压抑(路人甲:压抑还分享么……),也可以 ...
- CodeForces - 645D Robot Rapping Results Report(拓扑排序)
While Farmer John rebuilds his farm in an unfamiliar portion of Bovinia, Bessie is out trying some a ...
- BZOJ3832[Poi2014]Rally——权值线段树+拓扑排序
题目描述 An annual bicycle rally will soon begin in Byteburg. The bikers of Byteburg are natural long di ...
- 带权图的最短路径算法(Dijkstra)实现
一,介绍 本文实现带权图的最短路径算法.给定图中一个顶点,求解该顶点到图中所有其他顶点的最短路径 以及 最短路径的长度.在决定写这篇文章之前,在网上找了很多关于Dijkstra算法实现,但大部分是不带 ...
- 拓扑排序&关键路径
拓扑排序:AOV网 概念 example:选课问题:AOV网 顶点活动(Activity On Vertex)网是指用顶点表示活动,而用边集表示活动关系的有向图. 在这个例子中,课程为结点,而有向边表 ...
- 洛谷P1073 Tarjan + 拓扑排序 // 构造分层图
https://www.luogu.org/problemnew/show/P1073 C国有 n n个大城市和 mm 条道路,每条道路连接这 nn个城市中的某两个城市.任意两个城市之间最多只有一条道 ...
- 算法:图(Graph)的遍历、最小生成树和拓扑排序
背景 不同的数据结构有不同的用途,像:数组.链表.队列.栈多数是用来做为基本的工具使用,二叉树多用来作为已排序元素列表的存储,B 树用在存储中,本文介绍的 Graph 多数是为了解决现实问题(说到底, ...
- 【bzoj1093】[ZJOI2007]最大半连通子图 Tarjan+拓扑排序+dp
题目描述 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:对于u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u的有向路径. ...
随机推荐
- WP8.1的shell:SystemTray去哪了?
WP8.1 中的SystemTray被 StatusBar 代替了.在Windows.UI.ViewManagement 命名空间下,而且只能在后台代码中设置,XAML中不行.用法是这样的: Stat ...
- 一定要在commit之前做RAR备份,这样在出问题的时候,可以排除别人代码的干扰
否则找错实在是太痛苦了,根本不知道来自哪里...而这样上面那样做,可以节省时间.
- 理解typedef(转)
// 从别人那转的,调整下格式便于阅读. 首先请看看下面这两句: typedef ]; typedef void (*p)(void); 如果你能一眼就看出它们的意思,那请不要再往下看了.如果你不太理 ...
- C# winform 主界面打开并关闭登录界面
在winform 界面编程中,我们有时候要在主界面打开之前先显示登录界面,当登录界面用户信息校验正确后才打开主界面,而这时登陆界面也完成使命该功成身退了. 目前有两种方法可实现: 方法1. 隐藏登录界 ...
- 使用QPainter的drawPixmap()绘制多幅图片 good
众所周知,使用QLabel的setPixmap()就可以将图片显示出来,做视屏解码后显示也可以如此.但是为何我今天还要费力使用基函数drawPixmap()来做绘图?理由有这么些吧: 1.使用QLab ...
- linux+php+swoole解决方案
服务器接收巨量的并发我使用linux+php+swoole解决方案.简单快速高效 并发量大 稳定 http://www.swoole.com/
- better later than never
工作一年半,写程序也有几年了,终于开了个博客,记录一下遇到的问题和解决方法,和其他需要记录的东西.希望自己不会懒……已经开通两周了才开始写,唉……
- python合并多个文件
import os filelist=os.listdir('/root/Music') for item in filelist: print item newfile=open('/root/Mu ...
- Python 爬虫从入门到进阶之路(七)
在之前的文章中我们一直用到的库是 urllib.request,该库已经包含了平常我们使用的大多数功能,但是它的 API 使用起来让人感觉不太好,而 Requests 自称 “HTTP for Hum ...
- Varnish动静分离配置示例
动静分离 [root@varnish ~]# vim /etc/varnish/default.vclvcl 4.0;backend web { .host = "192.168.30.15 ...