拓扑排序简介

拓扑排序是一种图论排序方式,要了解拓扑排序,首先要了解两个图论概念:入度出度。在有向无环图( D A G DAG DAG)中,一个点是多少弧的弧头称为入度,是多少弧的弧尾是出度
而作拓扑排序时,只需做以下步骤:

  1. 将入度为0的点存在一个队列内
  2. 每次取出一个点,将其能达到的点的入度减 1 1 1
  3. 将上一步操作中入度降为 0 0 0的点放在队尾
  4. 删除第 2 2 2步取出的那个点

最后,被删除的点的先后顺序就是这个图的拓扑序。
例如下面这个有向无环图的拓扑序便是: 4 → 3 → 6 → 5 → 1 → 2 4\rightarrow3\rightarrow6\rightarrow5\rightarrow1\rightarrow2 4→3→6→5→1→2

下面附上一般拓扑排序的部分代码

void topo(){//拓扑排序 for(int i=1;i<=n;i++){if(in[i]==0){q.push(i);}}while(!q.empty()){int p=q.front(); q.pop();for(int i=head[p];i>0;i=nxt[i]){int go=to[i];in[go]--;if(in[go]==0)q.push(go);}}
}

其中 i n [ i ] in[i] in[i]用来存储入度, g o [ i ] go[i] go[i]用来存储出度。

应用

我们看这样一道例题:

最大食物链计数

题目背景

你知道食物链吗?Delia 生物考试的时候,数食物链条数的题目全都错了,因为她总是重复数了几条或漏掉了几条。于是她来就来求助你,然而你也不会啊!写一个程序来帮帮她吧。

题目描述

给你一个食物网,你要求出这个食物网中最大食物链的数量。

(这里的“最大食物链”,指的是生物学意义上的食物链,即最左端是不会捕食其他生物的生产者,最右端是不会被其他生物捕食的消费者。)

Delia 非常急,所以你只有 1 1 1 秒的时间。

由于这个结果可能过大,你只需要输出总数模上 80112002 80112002 80112002 的结果。

输入格式

第一行,两个正整数 n 、 m n、m n、m,表示生物种类 n n n 和吃与被吃的关系数 m m m。

接下来 m m m 行,每行两个正整数,表示被吃的生物A和吃A的生物B。

输出格式

一行一个整数,为最大食物链数量模上 80112002 80112002 80112002 的结果。

样例 #1

样例输入 #1

5 7
1 2
1 3
2 3
3 5
2 5
4 5
3 4

样例输出 #1

5

提示

各测试点满足以下约定:


首先不难看出食物网是一张有向无环图( D A G DAG DAG),可以考虑通过 d p dp dp来求解,我们由相对若的生物指向相对强的生物来建边,如何建边可以考虑用邻接矩阵或者是我之前文章中提到的链式前向星算法引用链接
而状态转移方程并不难想,用数组 d p [ i ] dp[i] dp[i]存储以 i i i为终点的食物链条数,如果以 i i i为弧尾的弧的弧头是 j j j,那么我们有(在本题中注意取模)
d p [ j ] + = d p [ i ] dp[j]+=dp[i] dp[j]+=dp[i]
而最终的答案 a n s = ∑ d p [ i ] ( w h i l e g o [ i ] = 0 ) ans=\sum dp[i](while~go[i]=0) ans=∑dp[i](while go[i]=0)
最后附上本题解答

#include<bits/stdc++.h>
using namespace std;queue<int> q;int cnt=0,n,m;
int nxt[500005],to[500005],head[5005],dp[5005],in[5005];
bool has_son[5005];
const int mod=80112002;
long long ans=0;void add(int u,int v){//链式前向星 nxt[++cnt]=head[u];head[u]=cnt;to[cnt]=v;has_son[u]=true;
}void topo(){//拓扑排序 for(int i=1;i<=n;i++){if(in[i]==0){q.push(i);dp[i]=1;}}while(!q.empty()){int p=q.front(); q.pop();for(int i=head[p];i>0;i=nxt[i]){int go=to[i];dp[go]=(dp[go]+dp[p])%mod;in[go]--;if(in[go]==0)q.push(go);}}
}int read(){int x=0,f=1;char c=getchar();if(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f;
}int main(){n=read(),m=read(); for(int i=1;i<=m;i++){int u=read(),v=read();add(u,v);in[v]++;}topo();for(int i=1;i<=n;i++){if(!has_son[i]){ans=(ans+dp[i])%mod;}}cout<<ans;return 0;
}

拓扑排序介绍及其应用相关推荐

  1. 图论算法—图的拓扑排序介绍和Kahn算法原理解析以及Java代码的实现

    详细介绍了图的拓扑排序的概念,然后介绍了求拓扑序列的算法:Kahn算法的原理,最后提供了基于邻接矩阵和邻接表的图对该算法的Java实现. 阅读本文需要一定的图的基础,如果对于图不是太明白的可以看看这篇 ...

  2. aov建立Java模拟,数据结构之---C语言实现拓扑排序AOV图

    //有向图的拓扑排序 //杨鑫 #include #include #include #define MAX_NAME 3 #define MAX_VERTEX_NUM 20 typedef int ...

  3. 数据结构之图:有向图的拓扑排序,Python代码实现——26

    有向图的拓扑排序 拓扑排序介绍 什么是拓扑排序? 一个有向图的拓扑排序(Topological sort 或 Topological ordering)是根据其有向边从顶点U到顶点V对其所有顶点的一个 ...

  4. 用C语言编程实现拓扑排序,拓扑排序(一)之 C语言详解

    本章介绍图的拓扑排序.和以往一样,本文会先对拓扑排序的理论知识进行介绍,然后给出C语言的实现.后续再分别给出C++和Java版本的实现. 拓扑排序介绍 拓扑排序(Topological Order)是 ...

  5. 拓扑排序在实际项目中应用

    前言: 在实际工作场景中用到了拓扑排序,遂记录下来以供参考理解. 拓扑排序介绍: 首先,拓扑排序区别于一般的数值类排序算法,如冒泡排序.快速排序.堆排序等.它的处理对象是有向无环图DAG,最终是把有向 ...

  6. 拓扑排序Kahn算法

    拓扑排序 介绍 思路 操作过程 完美图解 代码模板 介绍 拓扑排序,整体是给出n个事件先后关系,来确定n个事件最终的先后关系 思路 很好理解 操作过程 我们可以理解成一个有向图如果x事件在y事件的前面 ...

  7. 拓扑排序之java实现_有向图和拓扑排序Java实现

    package practice; import java.util.ArrayDeque; import java.util.Iterator; import java.util.Stack; pu ...

  8. 拓扑排序(topological sorting)介绍及Python实现

    目录 1. 拓扑排序 2. 拓扑排序存在的前提 3. 拓扑排序的唯一性问题 4. 拓扑排序算法原理 4.1 广度优先遍历 4.2 深度优先遍历 5. 代码实现 5.1 Graph类的实现 5.2 广度 ...

  9. networkx 有向图强连通_leetcode刷题(四):搜索(深度优先搜索,广度优先搜索)拓扑排序,强连通分量...

    在开始今天的话题之前,我们先了解一个概念,什么是图的遍历? 图的遍历就是从图中某一点出发访遍图中其余剩余定点,且每个顶点仅被访问一次,这个过程叫做图的遍历. 图的遍历主要被分为深度优先遍历和广度优先遍 ...

最新文章

  1. 你还在这样学习Python吗?真的不可以
  2. R语言生存分析模型简介及survival包实现实战:基于survival包lung数据集
  3. anaconda重新安装pytorch,使用GPU加速
  4. python下载大文件-使用python通过FTP下载大文件
  5. 对List中对象的去重
  6. ubuntu下修改文件夹权限
  7. 云漫圈 | 如何给女朋友解释什么是HTTP
  8. 微软的自动更新问题,导致svchost.exe占用cpu超过50%
  9. Qt之QHeaderView自定义排序(获取正确的QModelIndex)
  10. Atom安装或更新插件失败的解决方案
  11. python 笔记数据类型
  12. 11.文件与文件系统的压缩与打包
  13. HTTP协议中GET、POST和HEAD的介绍
  14. 上班按小时的怎么记,小时工计时怎么用便签记上个月的工时
  15. 如何使用VBS调用VBA函数
  16. python机械臂写字_SCARA机器人 机械手臂 写字机 DIY 视觉识别
  17. Dreamweaver cc 2019
  18. 《XX》――SY 手把手教你如何XX
  19. 内网安全——域控提权-CVE-2020-1472NTLM中继攻击
  20. 2009-2020年天猫“双十一”成交额统计情况

热门文章

  1. 喜欢你,才不顾一切的作践自己:QQ伤感日志
  2. docker-redis
  3. 计蒜客: 德克萨斯长角牛 (最短路)
  4. 一起学习如何使用Photoshop绘制像素图片
  5. 作品集十(平面设计)
  6. 2018 CTCS第五届“智能出行”中国企业差旅合规高峰论坛即将开幕
  7. 鸿蒙系统小米电视,鸿蒙系统被曝光!首款鸿浩818芯片,华为智慧屏对标小米电视...
  8. [cocos2d-iphone]ios6截图问题
  9. 阿里云ECS服务器跨账号迁移
  10. HyperLynx(二)LineSim的基本操作