有向图的拓扑序列

简介: 拓扑排序

给定一个 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 <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;

const int N=1e6+10;

int h[N], e[N], ne[N], idx;
int n, m;
int q[N], d[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(!d[i])
        {
            q[++tt]=i;
        }
    }
    while(hh<=tt)
    {
        int t=q[hh++];
        for(int i=h[t];i!=-1;i=ne[i])
        {
            int j=e[i];
            d[j]--;
            if(d[j]==0) q[++tt]=j;
        }
    }
    return tt==n-1;
}


int main()
{
    scanf("%d %d", &n, &m);
    memset(h, -1, sizeof h);
    while(m--)
    {
        int a, b;
        scanf("%d %d", &a, &b);
        add(a, b);
        d[b]++;
    }
    if(topsort())
    {
        for(int i=0;i<n;i++) printf("%d ", q[i]);
        printf("\n");
    }
    else printf("-1\n");
    return 0;
}
相关文章
|
6月前
|
机器学习/深度学习 测试技术
【深度优先搜索】【树】【有向图】【推荐】685. 冗余连接 II
【深度优先搜索】【树】【有向图】【推荐】685. 冗余连接 II
|
6月前
|
存储 算法 C++
【C/C++ 数据结构 】无向图和有向图的差异
【C/C++ 数据结构 】无向图和有向图的差异
192 0
|
30天前
acwing 848 有向图的拓扑序列
acwing 848 有向图的拓扑序列
24 0
|
6月前
|
算法
图的应用(最小生成树,最短路径,有向无环图)
图的应用(最小生成树,最短路径,有向无环图
42 0
|
算法 测试技术 C#
C++算法:利用拓扑排序解决戳印序列
C++算法:利用拓扑排序解决戳印序列
图的基本术语,邻接矩阵、邻接表表示方法
图的基本术语,邻接矩阵、邻接表表示方法
|
C++ 索引
探索图论:无向图、有向图、加权图与无权图
引言 图论是数学中的一个精彩分支,通过图这种数据结构,我们可以更好地理解和分析现实世界中事物之间的关系。在图论中,有四种基本的图类型:无向图、有向图、加权图和无权图。本文将深入探讨这些图的概念,并通过C++代码示例帮助读者更加清晰地理解它们在抽象世界和实际问题中的应用。
744 0
|
存储 算法 搜索推荐
拓扑排序:求取拓扑序列
拓扑排序简单讲就是在可求拓扑序列的有向无回路图(有向无环图)中求取拓扑序列的排序算法。通俗讲就是按活动的先后次序进行排序的序列,并且每一个顶点只出现一次,它可以表述出完成某一项活动所需要的前置活动
79 0
拓扑排序:求取拓扑序列
|
存储 算法
SWUSTOJ 1057: 有向图的出度计算
SWUSTOJ 1057: 有向图的出度计算
102 0
搜索与图论-有向图的拓扑序列
搜索与图论-有向图的拓扑序列