拓扑排序

  • 引言
    有向无环图(Directed Acyclic Graph, DAG)是有向图的一种,字面意思的理解就是图中没有环。常常被用来表示事件之间的驱动依赖关系,管理任务之间的调度。拓扑排序是对DAG的顶点进行排序,使得对每一条有向边(u, v),均有u(在排序记录中)比v先出现。亦可理解为对某点v而言,只有当v的所有源点均出现了,v才能出现。

下图给出有向无环图的拓扑排序:
这里写图片描述

  • 实现:
    拓扑排序的实现算法有两种:入度表、DFS,其时间复杂度均为O(V+E)。

    1. 入度表

      • 找出图中0入度的顶点;
      • 依次在图中删除这些顶点,删除后再找出0入度的顶点;
      • 然后再删除……再找出……
      • 直至删除所有顶点,即完成拓扑排序
    2. 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值