算法学习系列(二十一):拓扑排序

这篇具有很好参考价值的文章主要介绍了算法学习系列(二十一):拓扑排序。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

引言

这个拓扑排序大家应该都听说过,用的地方也是很多,考研和面试也是经常考,其实这个排序算法的思想比较简单,应用的话就是可以用来判断一个图中是否存在一个环,本文主要是介绍拓扑排序的思想,以及一个简单的模板题,来帮助了解什么是拓扑排序,以及怎么写。

一、拓扑排序概念

英文名:topsort,叫拓扑排序纯属是音译,实际没啥具体含义哈
只有有向图无环图存在拓扑序列

思想:找入度为0的点加入序列,然后更新剩余的点,再找入度为零的点再次更新,直至图中所有的点全部加入到序列中,然后加入序列的顺序就是拓扑排序的顺序啦!
注:当有多个入度为0的点时,顺序随便,所以一个图的拓扑排序不是唯一的!

二、代码模板


const int N = 1e5+10;

int n, m;
int h[N], e[N], ne[N], idx;  //常规的链式存储法
int dist[N], q[N];  //dist[i]代表i号点的入度数

bool topsort()
{
    int hh = 0, tt = -1;
    
    for(int i = 1; i <= n; ++i)  //先把所有入度为0的点加入序列中
    {
        if(!dist[i]) q[++tt] = i;
    }
    
    while(hh <= tt)
    {
        auto t = q[hh++];
        
        for(int i = h[t]; i != -1; i = ne[i])
        {
            int j = e[i];
            dist[j]--;  //将其与之相连点的入度减1
            if(!dist[j]) q[++tt] = j;  //若入度减为0则加入到队列中
        }
    }
    
    return tt == n - 1;  //若所有点都加入队列中,说明存在拓扑序列
}

//输出拓扑序列,刚好为加入到队列的顺序
if(topsort())
{
    for(int i = 0; i < n; ++i) printf("%d ", q[i]);
}

三、例题

给定一个 n 个点 m 条边的有向图,点的编号是 1到 n,图中可能存在重边和自环。

请输出任意一个该有向图的拓扑序列,如果拓扑序列不存在,则输出 −1。

若一个由图中所有点构成的序列 A 满足:对于图中的每条边 (x,y),x在 A 中都出现在 y 之前,则称 A 是该图的一个拓扑序列。

输入格式
第一行包含两个整数 n 和 m。
接下来 m 行,每行包含两个整数 x 和 y,表示存在一条从点 x 到点 y 的有向边 (x,y)。

输出格式
共一行,如果存在拓扑序列,则输出任意一个合法的拓扑序列即可。
否则输出 −1。

数据范围
1≤n,m≤105

输入样例:
3 3
1 2
2 3
1 3
输出样例:
1 2 3
#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

const int N = 1e5+10;

int n, m;
int h[N], e[N], ne[N], idx;
int dist[N], q[N];

void add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

bool topsort()
{
    int hh = 0, tt = -1;
    
    for(int i = 1; i <= n; ++i)
    {
        if(!dist[i]) q[++tt] = i;
    }
    
    while(hh <= tt)
    {
        auto t = q[hh++];
        
        for(int i = h[t]; i != -1; i = ne[i])
        {
            int j = e[i];
            dist[j]--;  
            
            if(!dist[j]) q[++tt] = j;
        }
    }
    
    return tt == n - 1;
}

int main()
{
    memset(h, -1, sizeof h);
    
    scanf("%d%d", &n, &m);
    
    while(m--)
    {
        int a, b;
        scanf("%d%d", &a, &b);
        add(a,b);
        dist[b]++;
    }
    
    if(!topsort()) puts("-1");
    else for(int i = 0; i < n; ++i) printf("%d ", q[i]);
    
    return 0;
}

看一个用例还是可以的,然后这道题也AC了
算法学习系列(二十一):拓扑排序,算法,算法,学习文章来源地址https://www.toymoban.com/news/detail-795427.html

到了这里,关于算法学习系列(二十一):拓扑排序的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 算法沉淀——拓扑排序

    首先我们需要知道什么是拓扑排序? 在正式讲解拓扑排序这个算法之前,我们需要了解一些前置知识(和离散数学相关) 1、有向无环图: 指的是一个无回路的有向图。 入度:有向图中某点作为图中边的终点的次数之和 出度:有向图中某点作为图中边的起点的次数之和 2、

    2024年04月09日
    浏览(45)
  • 拓扑排序算法 -- dfs、bfs

    210. 课程表 II 该题用到「拓扑排序」的算法思想,关于拓扑排序,直观地说就是,让你把⼀幅图「拉平」,⽽且这个「拉平」的图⾥⾯,所有箭头⽅向都是⼀致的,⽐如上图所有箭头都是朝右的。 很显然,如果⼀幅有向图中存在环,是⽆法进⾏拓扑排序的,因为肯定做不到所

    2024年02月10日
    浏览(43)
  • 软件设计模式系列之二十一——观察者模式

    观察者模式(Observer Pattern)是一种行为型设计模式,它允许对象之间建立一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。这个模式也被称为发布-订阅模式,因为它模拟了一个主题(发布者)与多个观察者(订阅者)之间的

    2024年02月08日
    浏览(55)
  • 拓扑排序 (算法思想+图解+模板+练习题)

    有向无环图一定是拓扑序列,有向有环图一定不是拓扑序列。 无向图没有拓扑序列。 首先我们先来解释一下什么是有向无环图: 有向就是我们两个结点之间的边是有方向的,无环的意思就是整个序列中没有几个结点通过边形成一个圆环。 下图就是一个有向无环图,它也一定

    2024年02月03日
    浏览(70)
  • 探索经典算法 拓扑排序,字符串匹配算法,最小生成树

    拓扑排序、字符串匹配算法和最小生成树是计算机科学中常用的数据结构和算法,它们在解决各种实际问题中具有重要的应用价值。在本文中,我将详细介绍这三个主题,并提供相应的示例代码和应用场景,以帮助读者更好地理解和应用这些概念。 一、拓扑排序: 拓扑排序

    2024年02月05日
    浏览(52)
  • 【算法基础:搜索与图论】3.3 拓扑排序

    https://oi-wiki.org/graph/topo/ 本文主要学习拓扑排序相关知识。 拓扑排序的英文名是 Topological sorting。 拓扑排序要解决的问题是给一个 有向无环图 的 所有节点排序 。 我们可以拿大学每学期排课的例子来描述这个过程,比如学习大学课程中有:程序设计,算法语言,高等数学,

    2024年02月16日
    浏览(50)
  • 有向无环图的拓扑排序理解和算法

    有向无环图的拓扑排序理解和算法 有向无环图(DAG)定义 引用子维基百科的DAG定义, 在数学中,尤其是图论和计算机科学中,DAG是一类不含环的有向图(In mathematics, particularly graph theory, and computer science, a directed acyclic graph (DAG) is a directed graph with no directed cycles). 对比之前的有向图

    2024年02月04日
    浏览(45)
  • 【数据结构与算法】图的遍历与拓扑排序

    再上一篇中我们讲了树的两种存储方式:【数据结构与算法】图——邻接表与邻接矩阵 这一篇我们可以用数组来模拟邻接表。 假设现在我们要进行n次操作,实现无向图。 首先需要一个 保存是哪个节点 的数组 e 然后就是类似指针数组的 表 h ,每个表都会连一串单链表 e,ne

    2024年02月04日
    浏览(46)
  • Peter算法小课堂—拓扑排序与最小生成树

    讲拓扑排序前,我们要先了解什么是DAG树。所谓DAG树,就是指“有向无环图”。请判断下列图是否是DAG图 第一幅图,它不是DAG图,因为它形成了一个环。第二幅图,它也不是DAG图,因为它没有方向。第三幅图才叫真正的DAG图(DAG图不一定联通)。 那什么叫DAG图的拓扑排序呢

    2024年01月21日
    浏览(48)
  • 算法沉淀——BFS 解决拓扑排序(leetcode真题剖析)

    Breadth-First Search (BFS) 在拓扑排序中的应用主要是用来解决有向无环图(DAG)的拓扑排序问题。拓扑排序是对有向图中所有节点的一种线性排序,使得对于每一条有向边 (u, v),节点 u 在排序中都出现在节点 v 的前面。如果图中存在环路,则无法进行拓扑排序。 BFS 解决拓扑排序

    2024年02月21日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包