zoukankan      html  css  js  c++  java
  • 有向无环图的拓扑排序

    有向无环图的拓扑排序

    有向无环图(DAG),指不存在环的有向图。

    点的入度,指以这个点为结束点的边数。

    点的出度,指以这个点为出发点的边数。

    拓扑序就是对于节点的一个排列使得若(u,v)∈E,那么u在排列中出现的位置一定在v前面。

    而拓扑排序,则是一个用于求解拓扑序的方法(只需要求出一组解)

    根据以上描述,我们可以发现我们只要每次找到入度为0的节点,把该节点输出,并删除该节点和这个节点所有的后继,就可以的到一个图的拓扑排序了。

    像这张图,一种合法的拓扑排序就是1 2 4 3 5。

    在这里使用队列来实现拓扑排序。

    代码:

     1 #include<queue>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #define N 42000
     5 using namespace std;
     6 queue<int>p;
     7 int next[N],num,to[N],head[N],n,m,a,b,r[N],u,pre[N],ans[N],sum;
     8 void add(int false_from,int false_to){
     9     next[++num]=head[false_from];
    10     to[num]=false_to;
    11     head[false_from]=num;
    12 }
    13 int main(){
    14     scanf("%d%d",&n,&m);
    15     for(int i=1;i<=m;++i){
    16         scanf("%d%d",&a,&b);
    17         add(a,b);
    18         r[b]++;
    19     }
    20     for(int i=1;i<=n;++i)
    21         if(!r[i])
    22             p.push(i);
    23     while(!p.empty()){
    24         num=0;
    25         u=p.front();
    26         p.pop();
    27         ans[++sum]=u;
    28         for(int i=head[u];i;i=next[i]){
    29             r[to[i]]--;
    30             if(!r[to[i]])
    31                 pre[++num]=to[i];
    32         }
    33         sort(pre+1,pre+num+1);
    34         for(int i=1;i<=num;++i)
    35             p.push(pre[i]);
    36     }
    37     for(int i=1;i<=sum;++i)
    38         printf("%d ",ans[i]);
    39     return 0;
    40 }
    View Code
  • 相关阅读:
    为什么一看编程技术文章就这么兴奋呢?
    今天弄会了如何使用VB6使用AutoCAD提供的dll操作AutoCAD了
    简单工厂模式没想像中的难啊
    Linq本质论,C#3.0的特性。写的太好了!收藏!
    struct和class的区别
    饿了
    解决Eclipse 3.3+lomboz无法启动的问题
    IE8通过Acid2了
    Linux档案/目录 权限及修改
    Linux 初识man、info
  • 原文地址:https://www.cnblogs.com/jsawz/p/6837890.html
Copyright © 2011-2022 走看看