zoukankan      html  css  js  c++  java
  • 算法题--拓扑排序

    拓扑排序

      对一个有向无环图进行拓扑排序,所谓的拓扑排序就是将一系列事件按照一定的顺序进行排列,要求是在前面的事件是后面事件的先决条件,也就是说,要想进行后面的事件,必须要将该事件前面全部的先决条件完成才可以进行该事件,在有向无环图中体现某事件是另一个事件的先决条件的是,每条边的起点是它的终点的先决条件。

    典型例题:

    1 有向图的拓扑序列

    题意给定一个n个点m条边的有向图,点的编号是1到n,图中可能存在重边和自环。请输出任意一个该有向图的拓扑序列,如果拓扑序列不存在,则输出-1。若一个由图中所有点构成的序列A满足:对于图中的每条边(x, y),x在A中都出现在y之前,则称A是该图的一个拓扑序列。

    题解:这是一个典型的拓扑排序的模板题。解法是我们可以利用向量来记录一条边的起点和终点:vec[u].push_back(v);这表示点u到点v有一条边,且u是v的先决条件,同时利用indeg[v]++,对点v的入度进行计数,这一点非常重要,因为我们要进行拓扑排序,就要从入度为0的点开始,也就是说要从没有先决条件的事件开始。之后就可以进行拓扑排序了。在进行拓扑排序的时候,我们可以用一个队列先将原图中入度为零的点存储起来(可能不止一个),这样,我们就找到了开始的起点,同时也代表我们将这一个点放进了拓扑序列,这样的话,我们此时就应该将以它为先决条件的点的入度就应该减一,如果减一后,该点的入度变为0,则在将该点放入队列,以判断队列是否为空为循环条件,每一次开始循环是队列的对头元素执行出列,循环往复的执行该循环,直到将所有的点都判断一遍,这样就可以都到一个拓扑序列了。同时,可以通过判断输出节点的个数判原图是否存在拓扑序列,若节点个数与输入的n相等,则存在,反之,不存在。

    代码

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<queue>
    using namespace std;
    const int maxn=1e5+10;
    vector<int> vec[maxn];
    queue<int> que;
    queue<int> ans;
    int num=0;
    int indeg[maxn];
    int n,m;
    int topSort(){
        while(!que.empty()) que.pop();
        for(int i=1;i<=n;i++){
            if(indeg[i]==0){
                que.push(i);
            }
        }
        while(!que.empty()){
            int now=que.front();
            que.pop();
            num++;
            ans.push(now);
            for(int i=0;i<vec[now].size();i++){
                if(--indeg[vec[now][i]]==0){
                    que.push(vec[now][i]);
                }
            } 
        }
        if(num==n) return 0;
        else return 1;
    }
    int main(){
        cin>>n>>m;
        for(int i=0;i<n;i++) vec[i].clear();
        int u,v;
        while(m--){
            cin>>u>>v;
            vec[u].push_back(v);
            indeg[v]++;
        }
        if(topSort()!=0) cout<<-1;
        else{
            int ni=ans.size();
            for(int i=0;i<ni;i++){
                cout<<ans.front();
                ans.pop();
                if(i<ni-1){
                    cout<<" ";
                }
            }
        }
    
        return 0;
    } 

    更多信息可以参考博客:https://www.luogu.com.cn/blog/80049/kuai-su-ru-shou-ta-pu-pai-xu

  • 相关阅读:
    通过远程linux shell传输文件
    Windows下 postgresql安装报错
    python安装tesserocr错误解决办法
    django makemigrations
    Windows下eric安装的几个小问题
    _WinMain结构
    python学习第七天——输入输出、file
    python学习第六天——模块的概念(重要)
    python学习第五天——函数(重点)
    python学习第四天——控制流
  • 原文地址:https://www.cnblogs.com/blogxsc/p/12815114.html
Copyright © 2011-2022 走看看