关于拓扑排序

本文详细介绍了拓扑排序的概念及其在解决有向无环图中排序问题的应用。文章首先定义了拓扑排序的基本概念,随后通过具体实例展示了两种实现拓扑排序的方法:基于队列的方法和深度优先搜索方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

拓扑排序:

  • 对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。
  • *********************************************************************************************************************************************拓扑排序Topological Sort
  • 问题: 给定一组有先决条件约束的工作、课程等, 希望以某种线性顺序组织这些任务,且不违反任何 的先决条件.
    可以用一个有向无环图(DAG)来模拟这个问题。因为任务之间存在先决条件关系,即顶点之间有方向性,因此图是有方向的。图又需要是无回路的, 因为回路中隐含了相互冲突的条件,从而使某些 条件不可能在不违反任何先决条件的情况下得到实现. 将一个DAG中所有顶点在不违反先决条件规定的基础上排成线性序列的过程称为拓扑排序。
  • 如何进行拓扑排序?
  • 一、从有向图中选取一个没有前驱 的顶点,并输出之;
  • 二、从有向图中删去此顶点以及所 有以它为尾的弧;
  • 重复上述两步,直至图空,或者 图不空但找不到无前驱的顶点为止。
  • 如何进行拓扑排序? 
  • 拓扑序列可通过对图进行深度优先搜索来寻找
  • 对图进行深度优先搜索来寻找, 某个顶点被访问时,不进行任何处理; 当递归返回到此顶点时,打印这个顶点。 这就产生一个逆序的拓扑序列。
  • 序列从哪个顶点开始并不重要,因为所有顶点最终都被访问到。
  • 题目poj1094

 

  • Sorting It All Out

    Time Limit: 1000MS Memory Limit: 10000K
    Total Submissions: 38599 Accepted: 13601

    Description

    An ascending sorted sequence of distinct values is one in which some form of a less-than operator is used to order the elements from smallest to largest. For example, the sorted sequence A, B, C, D implies that A < B, B < C and C < D. in this problem, we will give you a set of relations of the form A < B and ask you to determine whether a sorted order has been specified or not.

    Input

    Input consists of multiple problem instances. Each instance starts with a line containing two positive integers n and m. the first value indicated the number of objects to sort, where 2 <= n <= 26. The objects to be sorted will be the first n characters of the uppercase alphabet. The second value m indicates the number of relations of the form A < B which will be given in this problem instance. Next will be m lines, each containing one such relation consisting of three characters: an uppercase letter, the character "<" and a second uppercase letter. No letter will be outside the range of the first n letters of the alphabet. Values of n = m = 0 indicate end of input.

    Output

    For each problem instance, output consists of one line. This line should be one of the following three: 

    Sorted sequence determined after xxx relations: yyy...y. 
    Sorted sequence cannot be determined. 
    Inconsistency found after xxx relations. 

    where xxx is the number of relations processed at the time either a sorted sequence is determined or an inconsistency is found, whichever comes first, and yyy...y is the sorted, ascending sequence. 

    Sample Input

    4 6
    A<B
    A<C
    B<C
    C<D
    B<D
    A<B
    3 2
    A<B
    B<A
    26 1
    A<Z
    0 0
    

    Sample Output

    Sorted sequence determined after 4 relations: ABCD.
    Inconsistency found after 2 relations.
    Sorted sequence cannot be determined.
    
  • 第一种是Queue_based

  • #include <iostream>
    #include <stdio.h>
    #include <string.h>
    using namespace std;
    char c[4];
    int tu[30][30], rudu[30], temp[30];
    int result[30];
    int tupo(int n)
    {
        memset(temp, 0, sizeof(temp));
        memset(result, 0, sizeof(result));
        int flag = 1, cnt = 0;
        for(int i=1; i<=n; i++)
            temp[i] = rudu[i];
        for(int i=1; i<=n; i++)
        {
            int m = 0, pos;
            for(int j=1; j<=n; j++)
            {
                if(!temp[j])
                {
                    m++;
                    pos = j;
                }
            }
            if(!m)//一旦发现环,返回0
            return 0;
            if(m > 1)//答案不唯一时
                flag = -1;
            result[cnt++] = pos;
            temp[pos] = -1;
            for(int j=1; j<=n; j++)
            {
                if(tu[pos][j])
                    temp[j]--;
            }
        }
        return flag;
    }
    int main()
    {
        int n, m;
        while(scanf("%d%d", &n, &m)==2 && n && m)
        {
            memset(tu, 0, sizeof(tu));
            memset(rudu, 0, sizeof(rudu));
            int flag = 0;
            for(int i=1; i<=m; i++)
            {
                scanf("%s", c);
                int x = c[0] - 'A' + 1;
                int y = c[2] - 'A' + 1;
                tu[x][y] = 1;
                rudu[y]++;
                if(flag) continue;
                int s = tupo(n);
                if(!s)
                {
                    cout << "Inconsistency found after " << i << " relations.\n";
                    flag = 1;
                }
                else if(s==1)
                {
                    cout << "Sorted sequence determined after " << i << " relations: ";
                    for(int k=0; k<n; k++)
                        printf("%c", result[k]+'A'-1);
                    cout << '.'<< endl;
                    flag = 1;
                }
            }
            if(!flag)
                cout << "Sorted sequence cannot be determined.\n";
        }
        return 0;
    }
    //4 6
    //A<B
    //A<C
    //B<C
    //C<D
    //B<D
    //A<B
    //3 2
    //A<B
    //B<A
    //26 1
    //A<Z
    //0 0
    //Sorted sequence determined after 4 relations: ABCD.
    //Inconsistency found after 2 relations.
    //Sorted sequence cannot be determined.

  • 第二种做法就是DFS咯,,我还没做出来,未完待续haha

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值