我们来看看拓扑排序

简介: 我们来看看拓扑排序

我们首先来看看百度百科对拓扑序列的解释

拓扑序列是顶点活动网中将活动按发生的先后次序进行的一种排列。 拓扑排序,是对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。

百度百科给的求的过程,我们一起来了解一下

对于一个给定的有向图,得到其拓扑序列的步骤如下:

①从图中选择一个入度为0的顶点,并输出该顶点;

②从图中删除该顶点及其相关联的有向边,调整被删除有向边的终点的入度(入度减1);

③重复①和②;

④直到所有顶点均被输出,拓扑序列完成;否则,无拓扑序列。

可以证明,任何一个无环的有向图一定有拓扑序列,有环的有向图则无拓扑序列。

相信大家看了度娘的解释一定清楚了吧,那么我们接下来就把acwing上的一道题拿来练练手!

我们先看下题目描述:(这道题可以在acwing 上搜索 有向图的拓扑序列 来查看额原题额,顺便也把链接放这吧,就是不知道进不进得去,进不去就自己去acwing 上搜索。有向图的拓扑序列)

本着下面这个原则,最终成功拿下了!

while(有bug){
  改bug
  if(accept)break;
}

成功拿下的Code

#include<bits/stdc++.h>
using namespace std;
int n, m;
const int N = 1000010;
int h[N], ne[N], e[N], idx;
int d[N];//d数组表示某点的入度
void add(int a,int b){//存储图,以邻接表的方式
    e[idx] = b;
    ne[idx] = h[a];
    h[a] = idx++;
}
int q[N];//定义个队列(数组模拟队列),装入度为0的点。 (这也可以不用队列,就看做是个普通的数组也行)
int topSe(){
    int hh = 0, tt = 0;//初始化队头和队尾
    for (int i = 1; i <= n;i++){
        if(!d[i]) q[tt++] = i; //把入度为0的点入队
    }
    while(hh<=tt){//队列不空就执行下面的
        int t = q[hh++];//取出队头的数,然后将对头的数出队。(这就是数组模拟队列的优点吧)
        for (int i = h[t]; i != -1;i=ne[i]){//遍历头结点的出边
            int j = e[i];//获取到达的点
            d[j]--;//将出边能到达的点,把入度减1(就是把边删掉)
            if(d[j]==0){//如果结点的入度为0
                d[j] = d[t] + 1;//距离 在上一个点的距离基础上 +1 
                q[tt++] = j;//将这个入度为0的点加入队列  
            }
        }
    }
    return tt == n;//队列长度等于n,返回1,否则返回0
}
int main(){
    memset(h, -1, sizeof(h));//将h数组全部置为-1,(这个看自己的写法,和上面得第20行有关)
    cin >> n >> m;
    for (int i = 0; i < m;i++){
        int a, b;
        cin >> a >> b;
        add(a, b);
        d[b]++;//因为是 a -> b ,所以,b 的入度要加 1
    }
    if(topSe()){//如果存在拓扑序列,则输出
        for (int i = 0; i <n;i++)//我们可以发现,队列中的入队顺序就是拓扑序列
            cout << q[i] << " ";
        cout << "\n";
    }else  //不存在则输出-1
        cout << "-1\n";
    return 0;
}

贴心时刻

担心各位老板难以滑动代码,我还特地的准备了图片版!



相关文章
|
4月前
拓扑排序
拓扑排序
21 0
|
4月前
|
NoSQL 容器 消息中间件
图、图的遍历及图的拓扑排序
图、图的遍历及图的拓扑排序
|
5月前
|
存储 人工智能 算法
【算法总结】拓扑排序
【算法总结】拓扑排序
30 0
|
10月前
|
搜索推荐
|
人工智能 自然语言处理 搜索推荐
拓扑排序算法
拓扑排序算法
90 0
|
存储 算法 Java
【数据结构与算法】有向图的拓扑排序
【数据结构与算法】有向图的拓扑排序
150 1
【数据结构与算法】有向图的拓扑排序
拓扑排序(邻接表实现)
拓扑排序(邻接表实现)
140 0
拓扑排序(邻接表实现)
|
机器学习/深度学习 存储
图的遍历 无向图深搜 宽搜
图的遍历 无向图深搜 宽搜
图的遍历 无向图深搜 宽搜
|
搜索推荐 算法
|
人工智能 BI
[Nowcoder] 有向无环图 | 拓扑排序简单应用
题目描述 Bobo 有一个 n 个点,m 条边的 有向无环图 (即对于任意点 v,不存在从点 v 开始、点 v 结束的路径)。 为了方便,点用 1 , 2 , … , n编号。 设count(x,y) 表示点 x 到点 y 不同的路径数量(规定count(x,x)=0,Bobo 想知道 ∑i=1n∑j=1ncount(i,j)⋅ai⋅bj 除以( 1 0 9 + 7 ) 的余数。 其中,a i , b j 是给定的数列。
108 0