有向图的拓扑序列

简介: 拓扑排序

给定一个 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;
}
相关文章
|
7月前
|
机器学习/深度学习 测试技术
【深度优先搜索】【树】【有向图】【推荐】685. 冗余连接 II
【深度优先搜索】【树】【有向图】【推荐】685. 冗余连接 II
|
2月前
acwing 848 有向图的拓扑序列
acwing 848 有向图的拓扑序列
28 0
|
7月前
|
算法
图的应用(最小生成树,最短路径,有向无环图)
图的应用(最小生成树,最短路径,有向无环图
50 0
|
算法 测试技术 C++
C++算法:图中的最短环
C++算法:图中的最短环
图的基本术语,邻接矩阵、邻接表表示方法
图的基本术语,邻接矩阵、邻接表表示方法
|
存储 算法 搜索推荐
拓扑排序:求取拓扑序列
拓扑排序简单讲就是在可求拓扑序列的有向无回路图(有向无环图)中求取拓扑序列的排序算法。通俗讲就是按活动的先后次序进行排序的序列,并且每一个顶点只出现一次,它可以表述出完成某一项活动所需要的前置活动
84 0
拓扑排序:求取拓扑序列
|
存储 算法
SWUSTOJ 1057: 有向图的出度计算
SWUSTOJ 1057: 有向图的出度计算
117 0
|
机器学习/深度学习 存储 算法
1065: 无向图的连通分量计算
1065: 无向图的连通分量计算
117 0
搜索与图论-有向图的拓扑序列
搜索与图论-有向图的拓扑序列
|
算法
Dijkstra算法:单元最短路径算法
Dijkstra算法:单元最短路径算法
184 0