图论-拓扑排序详解

拓扑排序(topsort)详解

这篇随笔就信息学奥林匹克竞赛中图论的一个知识点——拓扑排序进行讲解。拓扑排序的内容比较基础,只要求读者学习过并了解信息学中图的相关定义和一些专业名词,但是拓扑排序的变形题目比较多,希望读者在看完本随笔后认真体会练习,掌握拓扑排序。

上课!

拓扑排序的定义

顾名思义,这是一种排序,确切地说,是一种图上排序,在一张有向无环图(注解:有向无环图即很多参考书和题解中所说的DAG)上进行排序,把其中的所有节点排成一个序列,使得图中的任意一对有边相连的节点(u,v)u要出现在v前。

所以我再次强调,拓扑排序只能用在有向无环图中!!

这样的线性序列我们称之为拓扑序。

注意,拓扑序不唯一!这个地方不明白的请自己画图理解(或者参考下面的那棵树)。

拓扑排序的实现原理

在讲解图的拓扑排序之前,我们可以用一棵树来加深对拓扑排序的理解(因为树是绝对没有环)。

我们随意地定义一棵有向树(如下图),如果我们想得到它的拓扑序,那会很简单,只需要先把根节点8号放进队列中,然后再放8号的任意一个儿子节点,继续此操作。直到节点全放进去为止。

我们会发现,问放进去的是任意的一个子节点,所以我们说拓扑序是不唯一的(在绝大多数情况下,你要非跟我抬杠说假如只有一条链,我也没办法)。

拓扑排序的实现

讲完了实现原理,我们来进行拓扑排序的代码实现,根据上面的原理,我们会发现,我们要保证拓扑序列的正确性,只需要把图中的入度为0的节点先放进拓扑序,然后把这个点和它所有的出边全部删掉,这样就还会出现一些入度为0的点,我们继续重复以上操作。

有细心的小伙伴会发现这个和算法中的宽搜很相似,没错,所谓宽搜和深搜,都是基于对树与图的深度/宽度优先遍历而定义的,所以拓扑排序的实现其实就是借助了宽搜的思想。

上模板:

void topsort()
{
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(rudu[j]==0)
            {
                x=j;
                top[++cnt]=j;
                rudu[j]--;
                break;
            }
        }
        for(int j=head[x];j;j=nxt[j])
            rudu[j]--;
    }
}

以上代码的top数组存拓扑序列,使用的是链式前向星存图并遍历。比较好理解,但是时间复杂度比较低。(所以仅供理解)

所以我们用C++STL来实现拓扑排序,这样会快很多。

模板:

void topsort()
{
    queue<int> q;
    for(int i=1;i<=n;i++)
        if(rudu[i]==0)
            q.push(i);
    while(q.empty())
    {
        int x=q.front();
        q.pop();
        top[++cnt]=x;
        for(int i=head[x];i;i=nxt[i])
        {
            int y=to[i];
            rudu[y]--;
            if(rudu[y]==0)
                q.push(y);
        }
    }
}

其实也很好理解啦...

注意,以上代码是针对于已经保证图是DAG的情况下而出现的,假如我们没有题目中DAG的保证,就要额外地判这个图是不是DAG,即很多题目中要求的“无解”情况。

怎么判断呢?

学到这里,我觉得你应该想到,如果最后得到的拓扑序列的长度等于节点总数,那么这个图就是DAG,否则就不是。

所以我们最后进行判断。

(你也可以使用STL中的vector容器)

代码:

if(cnt==n)
    //DAG操作
else
    //非DAG操作

拓扑排序的用途及一些技巧

拓扑排序的用途是解决一些依赖关系的题,一般来讲没有图论的基本要素(告诉你几个点,一眼就看出来这是一道图论题%%%),所以,我认为做拓扑排序题的难点在于如何建立一个和题意相符的图(建图坑死爹)。所以美其名曰拓扑排序是图论中最简单的内容,其实它的相关题目都很有思维含量,所以强烈建议各位同学多刷题多刷题

由于拓扑排序不唯一,所以有些坑爹题目要求拓扑序列的一些内容,比如按字典序等等。

这时我们把原本的队列拓扑排序换成优先队列拓扑排序。

注意,优先队列不能提速,不要以为找到了一份更好的模板,一定要读题~~!!

除了定义方式有点怪异其他的跟队列一样。

priority_queue<int,vector<int>,greater<int> >q;
//取队首的时候需要变成q.top();

下课!!祝同学们AK IOI!!

原文地址:https://www.cnblogs.com/fusiwei/p/11331916.html

时间: 2024-12-16 20:17:27

图论-拓扑排序详解的相关文章

拓扑排序详解与实现

目录 介绍 拓扑排序算法分析 拓扑排序代码实现 @(目录) 介绍 拓扑排序,很多人都可能听说但是不了解的一种算法.或许很多人只知道它是图论的一种排序,至于干什么的不清楚.又或许很多人可能还会认为它是一种啥排序.而实质上它是对有向图的顶点排成一个线性序列. 至于定义,百科上是这么说的: 对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边<u,v>∈E(G),则u在线性序列中出现在v之前.通常

转:【拓扑排序详解】+【模板】

转自:http://www.cnblogs.com/skywang12345/p/3711489.html 拓扑排序介绍 拓扑排序(Topological Order)是指,将一个有向无环图(Directed Acyclic Graph简称DAG)进行排序进而得到一个有序的线性序列. 这样说,可能理解起来比较抽象.下面通过简单的例子进行说明! 例如,一个项目包括A.B.C.D四个子部分来完成,并且A依赖于B和D,C依赖于D.现在要制定一个计划,写出A.B.C.D的执行顺序.这时,就可以利用到拓扑

拓扑排序详解

拓扑排序看起来很难,其实了解后不算难(思想非常清楚) 关键掌握思想后需要学会应用到具体的题目中去.(从入度为0到出度为0) 1.拓扑排序的介绍 对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前.     拓扑排序对应施工的流程图具有特别重要的作用,它可以决定哪些子工程必须要先执行,哪些子工程要在某些工程执行后才可以执行.为了形象地反映出整个

Excel2010排序详解

我倒是要看看这一天一篇的发表频率,能让我自己坚持多长时间. 今天跟大家分享的主要内容是在Excel中的筛选功能,这个功能应该是谁都用过,把一列数据按照从大到小,从小到大的,有意义或无意义的排列着.这个方法大家都会,用着几个按钮就都能搞定. 稍微复杂点的操作呢,比如按多关键字排序,按照单元格颜色排序,局部排序,按行横向排序,excel是如何完成的呢?耐心往下看. 1 按照多关键字排序.先看数据源,先按单据编号排序,在单据编号相同的情况下,按照商品编号排序,如果商品编号再相同,就按单据日期排序.这个

HDU 2647 Reward(图论-拓扑排序)

Reward Problem Description Dandelion's uncle is a boss of a factory. As the spring festival is coming , he wants to distribute rewards to his workers. Now he has a trouble about how to distribute the rewards. The workers will compare their rewards ,a

极角排序详解:

极角排序详解 名词释义: 在平面内取一个定点O,叫极点,引一条射线Ox,叫做极轴,再选定一个长度单位和角度的正方向(通常取逆时针方向).对于平面内任何一点M,用ρ表示线段OM的长度(有时也用r表示),θ表示从Ox到OM的角度,ρ叫做点M的极径,θ叫做点M的极角,有序数对 (ρ,θ)就叫点M的极坐标 四种极角排序代码详解: 1 struct point 2 { 3 double x,y; 4 }; 5 6 double cross(double x1,double y1,double x2,dou

python的sorted排序详解

排序,在编程中经常遇到的算法,我也在几篇文章中介绍了一些关于排序的算法.有的高级语言内置了一些排序函数.本文讲述Python在这方面的工作.供使用python的程序员们参考,也让没有使用python的朋友了解python.领略一番"生命有限,请用Python"的含义. 内置函数sorted()/list.sort()的使用 简单应用 python对list有一个内置函数:sorted(),专门用于排序.举例: >>> a=[5,3,6,1,9,2] >>&

数据结构与算法分析之----各种常用排序详解

1.选择排序 思想:在需要进行排序的序列中,每次把最小(或最大)的交换到最左边的位置 案例: 待排序数组: 5 2 6 8 4 1 选择过程:    5 2 6 8 4 1 => 2 5 6 8 4 1 => 1 5 6 8 4 2 => 1 4 6 8 5 2 => 1 2 6 8 5 4 => 1 2 5 8 6 4 => 1 2 4 8 6 5... 2.冒泡排序 思想:在需要进行排序的序列中,每次把最小(或最大)的推到最顶端,像气泡一样往上冒 案例: 待排序

图论-拓扑排序

拓扑排序(Topological sort) 拓扑排序是对有向无环图(DAG)顶点的一种排序,它使得如果存在u, v的有向路径,那么满足序中u在v前.拓扑排序就是由一种偏序(partical order)得到的一个全序(称为拓扑有序).偏序满足自反性,反对称性,传递性的序. 拓扑排序的思路很简单,就是每次任意找一个入度为0的点输出,并把这个点以及与这个点相关的边删除,实际算法中,用一个队列实现. 算法: 1.把所有入度为0的点入队Q; 2.若队Q非空,则点u出队,输出u,否则转4; 3.把所有与