拓扑排序算法总结

知识概览

  • 求图的拓扑序是图的宽搜的一个很经典的应用,拓扑序列是针对有向图来说的。

拓扑序列的定义是:

如果说一个点的序列满足对于图中的每条有向边(x, y),x都出现在y的前面,那就称这个序列是这个图的拓扑序列。 

备注:拓扑序列是指所有的边都是从前指向后的。只要有一个环,就一定没有拓扑序列。可以证明,有向无环图一定存在一个拓扑序列,所以有向无环图也被称为拓扑图。

必备知识:

  • 有向图的每个点有两个度,一个是入度,一个是出度。
  • 入度:一个点有几条边进来。
  • 出度:一个点有几条边出去。 

例题展示

题目链接

活动 - AcWing系统讲解常用算法与数据结构,给出相应代码模板,并会布置、讲解相应的基础算法题目。icon-default.png?t=N7T8https://www.acwing.com/problem/content/850/

代码

#include 
#include 
#include 

using namespace std;

const int N = 100010;

int n, m;
int h[N], e[N], ne[N], idx;
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]) q[++tt] = j;
        }
    }
    
    return tt == n - 1;
}

int main()
{
    cin >> n >> m;
    
    memset(h, -1, sizeof h);
    
    while (m--)
    {
        int a, b;
        cin >> a >> b;
        add(a, b);
        d[b]++;
    }
    
    if (topsort())
    {
        for (int i = 0; i < n; i++) printf("%d ", q[i]);
        puts("");
    }
    else puts("-1");
    
    return 0;
}

参考资料

  1. AcWing算法基础课

你可能感兴趣的:(经典算法总结,图论,算法,拓扑排序,有向无环图,拓扑图,拓扑序列,有向图,图论)