- 引言
有向无环图(Directed Acyclic Graph, DAG)是有向图的一种,字面意思的理解就是图中没有环。常常被用来表示事件之间的驱动依赖关系,管理任务之间的调度。拓扑排序是对DAG的顶点进行排序,使得对每一条有向边(u, v),均有u(在排序记录中)比v先出现。亦可理解为对某点v而言,只有当v的所有源点均出现了,v才能出现。
下图给出有向无环图的拓扑排序:
实现:
拓扑排序的实现算法有两种:入度表、DFS,其时间复杂度均为O(V+E)。入度表
- 找出图中0入度的顶点;
- 依次在图中删除这些顶点,删除后再找出0入度的顶点;
- 然后再删除……再找出……
- 直至删除所有顶点,即完成拓扑排序
DFS
在DFS中,依次打印所遍历到的顶点; 在遍历中离开某节点时输出到拓扑排序表中,从后往前依次输出即可(即添加到当前拓扑表的前面)。
#include <iostream>
#include <cstdio>
#include <cstring>
#define M 101
using namespace std;
bool Map[M][M]; //有向图
int flag[M];
int topo[M], t;
bool dfs(int cur, int n){
flag[cur] = -1; //表示正在访问
for(int i = 0; i < n; i++){
if(Map[cur][i] && i != cur){ // i!= cur目的为除去在对角线上的1
if(flag[i] < 0) //存在环
return false;
else if(!flag[i])
return dfs(i, n);
}
}
flag[cur] = 1;
topo[--t]= cur;
return true;
}
bool topoSort(int n){
t = n;
memset(flag, 0, sizeof(flag));
//初始化topo数组
for(int i = 0; i < n; i++)
topo[i] = i;
for(int i = n-1; i >= 0; i--){
if(!flag[i]){
if(!dfs(i, n))
return false;
}
}
return true;
}
void print_result(int n){
for(int i = 0; i < n; i++)
cout << topo[i] << " ";
cout << endl;
}
int main(){
int n;
cin >> n;
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
cin >> Map[i][j];
}
}
if(topoSort(n)){
print_result(n);
}else{
cout << -1 << endl; //拓扑排序不成功
}
return 0;
}