有向图的拓扑序列(拓扑排序)

news2025/1/23 10:35:52

给定一个 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≤10^5

输入样例:
3 3
1 2
2 3
1 3
输出样例:
1 2 3

有向无环图可以得到拓扑排序,拓扑排序就是只有从前指向后的边,比如图里面有一条从a指向b的边,那么在拓扑序列里面,a一定在b的前面。可以参考这篇文章:拓扑排序 (算法思想+图解+模板+练习题)_拓扑排序模板-CSDN博客

我们求一个拓扑序列,可以使用队列的方式,先找到图里面入度为0的点作为序列的起点,再将这些点删除,然后找到他们指向的点,此时这些指向的点存在入度为0的情况,再次入队,以此类推,知道图里所有点都入队为止。

bool topsort()
{
    int hh=0,tt=-1;  //队头队尾
    
    for(int i=1;i<=n;i++) //点的编号是从1开始的,从头开始找入度为0的点
    {
        if(in[i]==0) //这个点的入度为0就把它入队(队尾插入一个数,第一次插就是q[0],既是队头又是队尾)
        {
            q[++tt]=i;
        }
    }
    while(hh<=tt) //队列不为空的时候
    {
        int t=q[hh++]; //取出队头的点,它的入度为0
        
        for(int i=h[t];i!=-1;i=ne[i]) //遍历这个点的所有指向的点
        {
            int j=e[i]; 
            in[j]--;  //将指向的点入度-1
            if(in[j]==0)  //判断指向的点入度是否为0,如果为0就入队
            {
                q[++tt]=j;
            }
        }
    }
    return tt==n-1; //判断是否所有点都入队,有n个点,队列下标是从0开始的,所以第n个点的下标是n-1
    //如果所有的点都入队就说明他是一个有向无环图,是符合拓扑排序的
    //这里用数组模拟队列是为了能把这个拓扑序列保存下来,后面输出
}

这里我们用数组模拟队列是因为后面需要输出这个拓扑序列,而队列中入队的元素组合起来就是拓扑序列,如果用STL库里面的queue,删除之后就没法找到这些元素了,用数组模拟队列的删除只是将代表队头和队尾的下标改变了,实际上元素还存在队列里面。 

注意:拓扑排序的序列不唯一

示例代码:

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;

const int N=1e5+10;
int n,m;
int h[N],e[N],ne[N],idx; 
int q[N];  //队列,存放拓扑序列
int in[N];  //存放各个点的入度

void add(int a,int b) //从a到b的边
{
    e[idx]=b;
    ne[idx]=h[a];
    h[a]=idx;
    idx++;
}

bool topsort()
{
    int hh=0,tt=-1;  //队头队尾
    
    for(int i=1;i<=n;i++) //点的编号是从1开始的,从头开始找入度为0的点
    {
        if(in[i]==0) //这个点的入度为0就把它入队(队尾插入一个数,第一次插就是q[0],既是队头又是队尾)
        {
            q[++tt]=i;
        }
    }
    while(hh<=tt) //队列不为空的时候
    {
        int t=q[hh++]; //取出队头的点,它的入度为0
        
        for(int i=h[t];i!=-1;i=ne[i]) //遍历这个点的所有指向的点
        {
            int j=e[i]; 
            in[j]--;  //将指向的点入度-1
            if(in[j]==0)  //判断指向的点入度是否为0,如果为0就入队
            {
                q[++tt]=j;
            }
        }
    }
    return tt==n-1; //判断是否所有点都入队,有n个点,队列下标是从0开始的,所以第n个点的下标是n-1
    //如果所有的点都入队就说明他是一个有向无环图,是符合拓扑排序的
    //这里用数组模拟队列是为了能把这个拓扑序列保存下来,后面输出
}

int main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n>>m;
    memset(h,-1,sizeof(h));  //领接表初始化
    
    while(m--)
    {
        int a,b;
        cin>>a>>b;
        add(a,b);  //增加一条从a到b的边
        in[b]++;
    }
    
    if(!topsort()) //如果拓扑序列不存在就输出-1
    {
        puts("-1");
    }
    else
    {
        for(int i=0;i<n;i++)
        {
            cout<<q[i]<<" "; //按顺序输出它的拓扑序列
        }
        cout<<endl;
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1289884.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VSCode之C++ CUDA入门:reduce的N+1重境界

背景 Reduce是几乎所有多线程技术的基础和关键&#xff0c;同样也是诸如深度学习等领域的核心&#xff0c;简单如卷积运算&#xff0c;复杂如梯度聚合、分布式训练等&#xff0c;了解CUDA实现reduce&#xff0c;以及优化reduce是理解CUDA软硬件连接点的很好切入点。 硬件环境&…

wait notify

文章目录 1. API 介绍2. 怎么使用wait、notify2.1 sleep 和 wait 的区别2.2 sleep 和 wait 的使用模板 1. API 介绍 都属于 Object 对象的方法。必须获得此对象的锁&#xff0c;才能调用这几个方法&#xff0c;只有重量级锁才能调用wait、notify obj.wait() 让进入 object 监…

JMETER安装

jmeter 下载 https://jmeter.apache.org/download_jmeter.cgi 启动 jmeter.bat # GUI默认模式启动jmeterw.cmd # GUI默认启动(启动不带Windows shell窗口)jmeter-n.cmd # 放置一个JMX文件&#xff0c;命令行启动Jmeter测试jmeter-n-r.cmd # 放置一个JMX文件&#xff0c;命…

13、SQL注入——SQL盲注

文章目录 一、SQL盲注概述1.1 盲注1.2 盲注常用的函数 二、盲注payload2.1 布尔盲注2.2 时间盲注 一、SQL盲注概述 1.1 盲注 在SQL注入过程中&#xff0c;SQL语句执行后&#xff0c;选择的数据不能回显到前端页面&#xff0c;此时还需要利用一些方法进行判断或尝试&#xff0…

Linux常用指令详解

目录 前言&#xff1a; Linux的目录结构 Linux常用指令简介 whoami指令 ls指令 pwd指令 cd指令 tree指令 touch指令 mkdir指令 rmdir指令与rm指令 man指令 cp&#xff08;copy&#xff09;指令 mv&#xff08;move&#xff09;指令 cat指令 重定向及重定向的类型…

git常规操作流程(纯命令行操作)和一些注意事项

当你在单位拿到了git仓库,并利用公司给你的OA账号和邮箱完成了你的git基础配置,下面就是使用命令行的无错固定操作流程 如果你很着急,你可以直接跳到最后的总结部分 具体步骤 1.从仓库克隆代码到本地 这里的[codeUrl]就是你仓库的地址,当你在仓库点击图中绿色位置时,剪贴板…

深入了解UUID:生成、应用与优势

一、引言 在当今数字化时代&#xff0c;唯一标识一个对象的能力变得越来越重要。UUID&#xff08;Universally Unique Identifier&#xff0c;通用唯一标识符&#xff09;应运而生&#xff0c;作为一种保证全球唯一性的标识方法&#xff0c;广泛应用于各种场景。本文将详细介绍…

【头歌系统数据库实验】实验6 SQL的多表查询-2

目录 第1关&#xff1a;查询每个选手的信息及其提交的解答信息&#xff0c;没做题的选手不显示 第2关&#xff1a;查询做了1001题且耗时大于500&#xff08;time&#xff09;的选手信息 第3关&#xff1a;查询所有选手信息及其提交的解答信息&#xff0c;没做题的选手也要显…

计算机操作系统3

1.虚拟机 VM 两类虚拟机的对比&#xff1a; 2.进程 进程的特征&#xff1a; 进程状态的转换&#xff08;五大状态&#xff09; 3.进程控制原语的作用 4.线程 ​​​​​线程的属性 实现方式 5.调度算法的评价指标

2024年程序员面对经济下行的解决方式竟然是……

近些年大环境不好&#xff0c;经济下行的压力给到了我们每一个普通人的身上&#xff1a;降薪是潮流&#xff0c;裁员是趋势&#xff0c;找不到工作是常态。 在这样的环境下&#xff0c;我们曾一天三份工&#xff0c;只为家人温饱&#xff1b; 我们也曾一周七天连轴转&#xf…

GPU简介

1. GPU简介 GPU&#xff0c;即图形处理器&#xff08;Graphics Processing Unit&#xff09;&#xff0c;是一种专门设计用于图形渲染和图像处理的处理器。与传统的中央处理器&#xff08;CPU&#xff09;相比&#xff0c;GPU具有更强大的并行处理能力。 显卡作为电脑主机里的…

Linux学习——模拟实现mybash小程序

目录 一&#xff0c;跟正宗的bash见个面 二&#xff0c;实现一个山寨的bash 1.提示符 2.输入命令与回显命令 3.解析命令 4.执行命令 5.执行逻辑 三&#xff0c;全部代码 一&#xff0c;跟正宗的bash见个面 在这篇文章中&#xff0c;我会写一个myshell小程序。这个小程序…

问卷调查须避免的错误要点(02):避免逻辑错误与提升数据质量

在上篇文章中&#xff0c;我们讲到了4点在打造客户满意度调查中常犯的4个错误&#xff1a;提问偏颇或模糊不清、提问过多开放性问题、合并不同问题、合并不同问题。而在今天这篇文章中&#xff0c;我们将继续探讨做问卷调查要避免的其他错误要点。如果您也有这方面的需求&#…

大话数据结构-查找-线性索引查找

注&#xff1a;本文同步发布于稀土掘金。 4 线性索引查找 4.1 概述 索引就是把一个关键字与它对应的记录相关联的过程&#xff0c;一个索引由若干个索引项构成&#xff0c;每个索引项至少应包含关键字和其对应的记录在存储器中的位置等信息。 索引按照结构可分为线性索引、树…

Python Opencv实践 - 简单的AR项目

这个简单的AR项目效果是&#xff0c;通过给定一张静态图片作为要视频中要替换的目标物品&#xff0c;当在视频中检测到图片中的物体时&#xff0c;通过单应矩阵做投影&#xff0c;将视频中的物体替换成一段视频播放。这个项目的所有素材来自自己的手机拍的视频。 静态图片&…

力扣每日一题:2646. 最小化旅行的价格总和(2023-12-06)

力扣每日一题 题目&#xff1a;2646. 最小化旅行的价格总和 日期&#xff1a;2023-12-06 用时&#xff1a;30 m 14 s 时间&#xff1a;8ms 内存&#xff1a;42.98MB 思路&#xff1a;先统计旅行中每个节点路过的次数&#xff08;dfs方法&#xff09;&#xff0c;再计算减半后的…

智能优化算法应用:基于龙格-库塔算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于龙格-库塔算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于龙格-库塔算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.龙格-库塔算法4.实验参数设定5.算法结果6.参…

一个最新国内可用的免费GPT4,Midjourney绘画网站+使用教程

一、前言 ChatGPT GPT4.0&#xff0c;Midjourney绘画&#xff0c;相信对大家应该不感到陌生吧&#xff1f;简单来说&#xff0c;GPT-4技术比之前的GPT-3.5相对来说更加智能&#xff0c;会根据用户的要求生成多种内容甚至也可以和用户进行创作交流。 然而&#xff0c;GPT-4对普…

内核无锁队列kfifo

文章目录 1、抛砖引玉2、内核无锁队列kfifo2.1 kfifo结构2.2 kfifo分配内存2.3 kfifo初始化2.4 kfifo释放2.5 kfifo入队列2.6 kfifo出队列2.7 kfifo的判空和判满2.8 关于内存屏障 1、抛砖引玉 昨天遇到这样一个问题&#xff0c;有多个生产者&#xff0c;多个消费者&#xff0c…

❀My学习Linux命令小记录(14)❀

目录 ❀My学习Linux命令小记录&#xff08;14&#xff09;❀ 56.man指令 57.whatis指令 58.info指令 59.--help指令 60.uname指令 ❀My学习Linux命令小记录&#xff08;14&#xff09;❀ 56.man指令 功能说明&#xff1a;查看Linux中的指令帮助。 &#xff08;ps.man命…