首页 > 其他分享 >848. 有向图的拓扑序列

848. 有向图的拓扑序列

时间:2023-08-03 21:02:49浏览次数:29  
标签:输出 有向图 idx int 拓扑 848 序列

JWvFczgRNg.jpg

题目

给定一个 $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

思路

  1. 将初始情况下入度为0的点加入队列
  2. 宽度优先搜索bfs
while q
    t = q.pop()
    遍历t的所有出边t --> j
    d[j] -- 
    if d[j] == 0  说明j的入边都已排序
        q.push(j)

代码

#include <iostream>
#include <cstring>
#include <queue>

using namespace std;

const int N = 100010;

int n, m;
int h[N], e[N], ne[N], idx;
int d[N];  // 存储各个点的入度
int q[N], hh = 0, tt = -1;  // 存储队列,由于要打印入队的元素,所以要用这种方式

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

bool toposort()
{
    for (int i = 1; i <= n; i ++ )
        if (!d[i]) q[ ++ tt] = i;  // a = ++ i 先计算再赋值 a == i ++ 先赋值再计算
    
    while (hh <= tt)
    {
        int t = q[hh ++ ];

        for (int i = h[t]; i != -1; i = ne[i])
        {
            int j = e[i];
            if (-- d[j] == 0) q[ ++ tt] = j;
        }
    }

    return tt == n - 1;
}

int main()
{
    memset(h, -1, sizeof h);
    cin >> n >> m;
    while (m -- )
    {
        int a, b;
        cin >> a >> b;
        add(a, b);

        d[b] ++ ;
    }
    
    if (toposort())
    {
        for (int i = 0; i < n; i ++ ) cout << q[i] << " ";
    }
    else puts("-1");
    
    return 0;
}

标签:输出,有向图,idx,int,拓扑,848,序列
From: https://blog.51cto.com/u_16170343/6953213

相关文章

  • 【学习】拓扑排序
    拓扑排序学习笔记忘了学没学过了,就当没学过吧推歌:Oliver《D.S.》B站以外好像没有能听的概念拓扑排序的要求:有向无环图(TAG图)。拓扑序列中,一条有向边的起点一定排在它的重点的前面。由此可得拓扑序列求法:每次找到入度为\(0\)的点,把它加入序列中;删除它和由它出发的边,然后重......
  • 图/树的搜索/存储/拓扑排序
    深度优先搜索一条路走到黑回溯/剪枝每一个dfs都对应一个搜索树解决全排列,搜索所有可能解宽度优先搜索一层一层搜索解决最短路问题搜索方式数据结构空间特点DFSstackO(h)不具有最短性BFSqueueO(2^h)最短路树与图的存储有向图/树每......
  • 1848 Round 885 (Div. 2)
    VikaandHerFriends给定一张网格图,Vika在\((x,y)\)处,她的\(k\)个朋友分别在\((x_{1\simk},y_{1\simk})\)处,每次所有人都必须移动到相邻各格子,询问Vika能否永远逃离她烦人的朋友考虑对格子进行黑白染色,每次移动一定会变换格子颜色,那么只有相同颜色的人才会碰......
  • 洛谷 P1347 排序 - 拓扑排序
    P1347排序题意依次给一些具有排序关系的序列,问你在能否在若干个序列之后确定元素的顺序、判断元素关系存在矛盾、判断无法确认元素顺序思路对于每一个排序关系均进行toposort,后面就是toposort判环(出现矛盾),toposort判顺序,无法确认唯一关系。详见代码或看洛谷题解区代码......
  • 拓扑排序
    拓扑排序给定一张有向无环图,排出所有顶点的一个序列A满足:对于图中的每条有向边(x,y)x在A中的出现都在y之前,则称A是改图的顶点的一个拓扑序。如图所示,{2351746},{3215764}都是合法的拓扑序。用途:可以判断有向图中是否有环,可以生成拓扑排序Kahn算法实现拓扑排序e......
  • 虚拟机 NAT网络拓扑
    摘要目的:介绍虚拟机linux的NAT网络结构虚拟机网络结构分析:实际上,主机是开设了一个网卡,即vmnet8,这个网卡为主机开了一个虚拟网络而这个网卡也就是虚拟网络的出口,虚拟网络通过这个网卡实现网络地址转换要求,vmnet8和linux虚拟机在一个网段,也就是前面三位要相同具体地可......
  • 拓扑序
    通俗解释拓扑序就是一个包含依赖关系的序列假设做C之前必须做完B,做B之前必须做完A,拓扑序就是ABC实现思路维护各个节点的入度,将入度为0的节点入队将入度为0的节点的所有周边节点的入度减1,并将入度为0的节点入队当队列为空时,过程结束。若图中存在环路,则进入队列的元素个数<总节......
  • 一棵有根树的拓扑排序数量
    今日见到一个有趣的问题,就是本篇的题目。这里可以把它看作一个dp问题,\(f_i\)表示以\(i\)为根节点的子树的拓扑排序数量,要求出\(f_i\),就要知道\(f_j\)(\(j\inSon_i\)),但是它不是处理完一个子树,再处理另一个子树,它是穿插着来的,所以这个问题就变成了,已知\(k\)个序列,问有多少序列满足......
  • 拓扑排序
    定义:对一个有向图构造拓扑序列,排序类似流程图那样按先干什么后干什么这样排序拿大学教学安排举个例子(图来自oiwiki)先不要考虑操作系统到数据结构那条蓝线。那么我们要先学程序设计才能学习后面的算法语言,离散数学等等。那么在拓扑序列中,程序设计就要在算法语言,离散数学......
  • 数据结构与算法 头歌 图的拓扑排序算法
    数据结构与算法之图的拓扑排序算法导言拓扑排序是对有向无环图(DirectedAcyclicGraph,DAG)进行排序的一种算法。在实际开发中,拓扑排序算法常用于解决任务调度、编译顺序等问题。本文将介绍拓扑排序算法的实现过程,并帮助初学者理解该算法的原理及代码实现。拓扑排序流程以下......