AcWing 848:拓扑排序 ← 链式前向星存图

2024-06-13 04:04

本文主要是介绍AcWing 848:拓扑排序 ← 链式前向星存图,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

【题目来源】
https://www.acwing.com/problem/content/850/

【问题描述】
给定一个 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

【算法分析】
● 拓扑排序算法步骤:
(1)从有向图中选择一个无前驱(即入度为0)的顶点并且输出它。
(2)从图中删除该顶点及所有以它为尾的有向边。
(3)重复上述两步,直至不存在无前驱的顶点。
(4)若此时输出的顶点数小于有向图中的顶点数,则说明有向图中存在环,否则输出的顶点序列就是一个拓扑序列。

● 本题是拓扑排序的
模板题
本题的 STL vector 存图实现详见:https://blog.csdn.net/hnjzsyjyj/article/details/139635133

● 链式前向星:https://blog.csdn.net/hnjzsyjyj/article/details/139369904
val[idx]:存储编号为 idx 的边的值
e[idx]:存储编号为 idx 的结点的值
ne[idx]:存储编号为 idx 的结点指向的结点的编号
h[a]:存储头结点 a 指向的结点的编号

【算法代码】

#include <bits/stdc++.h>
using namespace std;const int maxn=1e5+5;
const int maxm=maxn<<1;
int e[maxm],ne[maxm],h[maxn],idx;
int din[maxn]; //in-degree
int tp[maxn]; //topological order
int n,m;void add(int a,int b) {e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}void topsort() {int hh=0, tt=-1;for(int i=1; i<=n; i++) {if(din[i]==0) tp[++tt]=i;}while(hh<=tt) {int t=tp[hh++];for(int i=h[t]; i!=-1; i=ne[i]) {int j=e[i];din[j]--;if(din[j]==0) tp[++tt]=j;}}if(tt==n-1) {for(int i=0; i<n; i++) {cout<<tp[i]<<" ";}} else cout<<"-1";
}int main() {cin>>n>>m;memset(h,-1,sizeof h);while(m--) {int a,b;cin>>a>>b;add(a,b);din[b]++;}topsort();return 0;
}/*
input:
3 4
1 2
2 1
2 3
3 1
output:
-1input:
5 5
1 3
1 5
2 1
3 4
3 5
output:
2 1 3 4 5
*/




【参考文献】
https://blog.csdn.net/hnjzsyjyj/article/details/139369904
https://blog.csdn.net/hnjzsyjyj/article/details/116307687
https://www.lmlphp.com/user/18593/article/item/587756/
https://blog.csdn.net/weixin_44356316/article/details/104755034
https://www.acwing.com/solution/content/103954/


 

这篇关于AcWing 848:拓扑排序 ← 链式前向星存图的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1056223

相关文章

数据结构9——排序

一、冒泡排序 冒泡排序(Bubble Sort),顾名思义,就是指越小的元素会经由交换慢慢“浮”到数列的顶端。 算法原理 从左到右,依次比较相邻的元素大小,更大的元素交换到右边;从第一组相邻元素比较到最后一组相邻元素,这一步结束最后一个元素必然是参与比较的元素中最大的元素;按照大的居右原则,重新从左到后比较,前一轮中得到的最后一个元素不参4与比较,得出新一轮的最大元素;按照上述规则,每一轮结

七种排序方式总结

/*2018.01.23*A:YUAN*T:其中排序算法:冒泡排序,简单排序,直接插入排序,希尔排序,堆排序,归并排序,快速排序*/#include <stdio.h>#include <math.h>#include <malloc.h>#define MAXSIZE 10000#define FALSE 0#define TRUE 1typedef struct {i

拓扑排序——C语言

拓扑排序(Topological Sorting)是一种用于有向无环图(DAG)的排序算法,其输出是图中所有顶点的线性排序,使得对于每条有向边 (u, v),顶点 u 在 v 之前出现。拓扑排序确定了项目网络图中的起始事件和终止事件,也就是顶点的执行顺序。         因为是有向无环图,所以拓扑排序的作用其实就是把先发生的排序在前面,后发生的排序到后面。 例如现在我们有一个

嵌入式学习——数据结构(哈希、排序)——day50

1. 查找二叉树、搜索二叉树、平衡二叉树 2. 哈希表——人的身份证——哈希函数 3. 哈希冲突、哈希矛盾 4. 哈希代码 4.1 创建哈希表 4.2  5. 算法设计 5.1 正确性 5.2 可读性(高内聚、低耦合) 5.3 健壮性 5.4 高效率(时间复杂度)时间复杂度越低,效率越高, 5.5 低储存(空间复杂度)空间复杂度越低,存储空间越少 6.排序算法 6.1 冒

leetcode刷题(40)——83. 删除排序链表中的重复元素

给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。 示例 1: 输入: 1->1->2 输出: 1->2 示例 2: 输入: 1->1->2->3->3 输出: 1->2->3 平时我们删除一个链表中的某个元素,一般都是以下的写法: temp.next = temp.next.next; 这样temp.next就被删除了 此题解法如下: class Solution

无法解决 equal to 运算中 Chinese_PRC_90_CI_AS 和 Chinese_PRC_BIN 之间的排序规则冲突

这是因为数据库 oa 和 hh 的编码格式不一样导致的 select  groupname as oper_id,name as oper_name from security_users where name collate Chinese_PRC_CI_AS not in (select oper_name from PDA_UsersAndPWD )

Java中的排序比较方式:自然排序和比较器排序

这里所说到的Java中的排序并不是指插入排序、希尔排序、归并排序等具体的排序算法。而是指执行这些排序算法时,比较两个对象“大小”的比较操作。我们很容易理解整型的 i>j 这样的比较方式,但当我们对多个对象进行排序时,如何比较两个对象的“大小”呢?这样的比较 stu1 > stu2 显然是不可能通过编译的。为了解决如何比较两个对象大小的问题,JDK提供了两个接口 java.lang.Comparab

php4种排序

arr=array(1,43,54,62,21,32,36,76,39);functionbubblesort( arr=array(1,43,54,62,21,32,36,76,39); function bubblesort(arr){ len=count( len=count(arr); //冒泡的轮数 //每轮需要冒泡的次数 for( k=1; k=1;k< len; len

快速排序.

给定你一个长度为 n 的整数数列。 请你使用快速排序对这个数列按照从小到大进行排序。 并将排好序的数列按顺序输出。 输入格式 输入共两行,第一行包含整数 n 。 第二行包含 n 个整数(所有整数均在 1∼109 范围内),表示整个数列。 输出格式 输出共一行,包含 n 个整数,表示排好序的数列。 数据范围 1≤n≤100000 输入样例: 5 3 1 2 4 5 输出样例: 1 2 3

JavaScripts数组里的对象排序的24个方法

1. 使用 Array.prototype.sort() 这是最基本、也是最常用的方法。sort() 方法会原地修改数组,并返回排序后的数组。你需要传入一个比较函数来定义排序逻辑。 const array = [{ name: 'Alice', age: 25 },{ name: 'Bob', age: 22 },{ name: 'Charlie', age: 30 }];// 按照年龄升序