zoukankan      html  css  js  c++  java
  • 拓扑序列

    一、什么是拓扑排序
    在图论中,拓扑排序(Topological Sorting)是一个有向无环图(DAG, Directed Acyclic Graph)的所有顶点的线性序列。且该序列必须满足下面两个条件:

    每个顶点出现且只出现一次。
    若存在一条从顶点 A 到顶点 B 的路径,那么在序列中顶点 A 出现在顶点 B 的前面。
    有向无环图(DAG)才有拓扑排序,非DAG图没有拓扑排序一说。

    例如,下面这个图:

     

    它是一个 DAG 图,那么如何写出它的拓扑排序呢?这里说一种比较常用的方法:

      1:从 DAG 图中选择一个 没有前驱(即入度为0)的顶点并输出。
      2:从图中删除该顶点和所有以它为起点的有向边。
      3:重复 1 和 2 直到当前的 DAG 图为空或当前图中不存在无前驱的顶点为止。后一种情况说明有向图中必然存在环。

     

    于是,得到拓扑排序后的结果是 { 1, 2, 4, 3, 5 }。

    通常,一个有向无环图可以有一个或多个拓扑排序序列。

    二、拓扑排序的应用
    拓扑排序通常用来“排序”具有依赖关系的任务。

    比如,如果用一个DAG图来表示一个工程,其中每个顶点表示工程中的一个任务,用有向边<A,B><A,B>表示在做任务 B 之前必须先完成任务 A。故在这个工程中,任意两个任务要么具有确定的先后关系,要么是没有关系,绝对不存在互相矛盾的关系(即环路)。

    三 题目:

    给定一个n个点m条边的有向图,图中可能存在重边和自环。

    请输出任意一个该有向图的拓扑序列,如果拓扑序列不存在,则输出-1。

    若一个由图中所有点构成的序列A满足:对于图中的每条边(x, y),x在A中都出现在y之前,则称A是该图的一个拓扑序列。

    输入格式

    第一行包含两个整数n和m

    接下来m行,每行包含两个整数x和y,表示存在一条从点x到点y的有向边(x, y)。

    输出格式

    共一行,如果存在拓扑序列,则输出拓扑序列。

    否则输出-1。

    数据范围

    1n,m1051≤n,m≤105

    输入样例:

    3 3
    1 2
    2 3
    1 3
    

    输出样例:

    1 2 3

    ############################################

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int N = 1e5+10;
     5 vector<int> h(N,-1), e(N,-1), ne(N,0); 
     6 int idx;
     7 int q[N],hh = 0, tt = -1;//模拟队列
     8 int d[N];//入度
     9 int n, m;
    10 
    11 void add(int a, int b){
    12     e[idx] = b;
    13     ne[idx] = h[a];
    14     h[a] = idx ++;
    15 }
    16 
    17 bool topsort(){
    18     for(int i = 1;i <= n;++i)
    19         if(d[i] == 0) q[++tt] = i;
    20     while(hh <= tt){
    21         int t = q[hh++];
    22         for(int i = h[t];i != -1;i = ne[i]){
    23             int tmp = e[i];
    24             -- d[tmp];
    25             if(d[tmp] == 0) q[++tt] = tmp;
    26         }
    27     }
    28     return tt == n-1;
    29 }
    30 
    31 int main(){
    32     cin >> n >> m;
    33     for(int i = 0;i < m;++i){
    34         int a, b;
    35         cin >> a >> b;
    36         add(a, b);
    37         d[b] ++;
    38     }
    39     if(topsort()){
    40         for(int i = 0;i < n;++i)cout << q[i] << " ";
    41     }else cout << -1 << endl;
    42     return 0;
    43 }
    View Code
  • 相关阅读:
    最优化方法(无约束)转载
    启动eclipse,弹出提示:java was started but returned exit code = 13
    前端开发之div实现table表格系列教程三:参数说明
    前端开发之div实现table表格系列教程二:拖动表格draggable
    前端开发之div实现table表格系列教程一:创建表格
    前端开发之弹出框系列教程十:通用参数说明
    前端开发之弹出框系列教程九:动画
    前端开发之弹出框系列教程八:自定义按钮栏
    前端开发之弹出框系列教程七:父页面与子窗口交互
    前端开发之弹出框系列教程六:win打开新窗口
  • 原文地址:https://www.cnblogs.com/sxq-study/p/12234100.html
Copyright © 2011-2022 走看看