拓扑排序
定义
拓扑序列是在有向无环图(DGA)中,使得图中任意两个顶点 u , v u,v u,v,如果存在一条 u − > v u->v u−>v的边,在拓扑序列中 u u u一定出现在 v v v的前面,这种序列叫做拓扑序列,而这种排序的过程被称为拓扑排序。一个图中的拓扑序列不止一个,例如下图中的拓扑序列可以是 1 , 5 , 2 , 3 , 6 , 4 1,5,2,3,6,4 1,5,2,3,6,4或者 5 , 1 , 2 , 3 , 6 , 4 5,1,2,3,6,4 5,1,2,3,6,4等,但是 5 , 2 , 1 , 6 , 3 , 4 5,2,1,6,3,4 5,2,1,6,3,4就不是这个图的拓扑序列。
实现
Kahn 算法(O(n+m))
前置知识:节点的度
从一个节点出去的边的条数被称为节点的出度,从一个节点进来的边的条数被称为节点的入度。
算法流程:
- 建立一个队列,将节点入度为零的点放入队列
- 取出队首元素,将队首元素放入拓扑序列数组中
- 扫描从队首元素出发的每一条边 ( x , y ) (x,y) (x,y),将扫描到的点y的入度减一。如果该点的入度为0,则将该点入队
- 重复2操作,直到队列为空
算法实现
void topsort(){
queue<int>q;
for(int i=1;i<=n;i++){
if(in[i]==0) q.push(i);//将入度为0的点入队
}
while(q.size()){
int t=q.front();//取出队头元素
q.pop();
a[++cnt]=t;//放入拓扑序列中
for(int i=h[t];i;i=ne[i]){
int x=e[i];
in[x]--;
if(in[x]==0) q.push(x);
}
}
}
应用
1.一个项目由子项目组成,而子项目之间有依赖关系(AOV图)
AOV图是以有向图中的顶点表示活动,有向边表示先后关系。
例题:P1983车站分级
2.判断是否有环
如果一个图中有环,其拓扑序中点的数量小于点的数量
对应题单:拓扑排序专练
拓展
AOE网
Activity On Edge:是一个带权的有向无环图,其中,顶点表示事件(Event),弧表示活动,权表示活动持续的时间。 入度为零的顶点成为源点,出度为零的顶点称为汇点。
AOE网可以求解:
- 完成整个工期的时间。
- 为缩短工期,应加快哪些活动。
求解方法:关键路径法
从源点到汇点具有最大长度的路径,关键路径上的所以活动都称作关键活动。
关键活动序列具有最长的总工期并决定了整个项目的最短完成时间,任何元素的延迟将直接影响项目的预期完成时间。
辅助学习:
例题: