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
  • 相关阅读:
    php升级5.3到5.4,5.5,5.6
    JNI NDK开发Crash错误定位 调试
    【转】移动端App测试实用指南
    【转】web测试内容及工具经典总结
    什么是比特币(bitcoin)
    读《活着》
    读《我们终将逝去的青春》
    自动make工具--CMake
    如何像黑客一样思考_转
    httpd在嵌入式中应用
  • 原文地址:https://www.cnblogs.com/jsawz/p/6837890.html
Copyright © 2011-2022 走看看