zoukankan      html  css  js  c++  java
  • 简析拓扑排序

    前言:巩固基础,发一发拓扑排序的理解。

     

    定义:

    在一个有向无环图中,若存在一个由图中的某些点所构成的序列A,满足:对于任意边(x,y),x在A中都出现在y之前,则A是该有向无环图顶点的一个拓扑序。求解序列A的过程即拓扑排序。

     

    实现思想:

    拓扑排序的思路实际很容易。因为拓扑序的性质是要满足边(x,y)中x出现在y之前,所以一个点若要加入拓扑序列中,则必须保证连向它的点都在它之前出现在该序列中,于是大致思路便有了,建立空队列,直接统计所有点的入度,然后将所有入度为0的点放入队列,取出队首并将其所连向的点的入度减1,不停判断入度为0的点并重复上述步骤,直到不存在入度为0的点为止(队列为空)。

     

    代码:

     

     1 #include<bits/stdc++.h>
     2 #define il inline
     3 using namespace std;
     4 const int N=10005,M=100005;
     5 int n,m,a[N],tot,cnt,ver[M],next[M],head[N],rd[N];
     6 il void add(int x,int y)    //邻接表加有向边
     7 {
     8     ver[++tot]=y,next[tot]=head[x],head[x]=tot;
     9     rd[y]++;
    10 }
    11 il void bfs(){    //拓扑排序用队列实现
    12     queue<int>q;
    13     for(int i=1;i<=n;i++)
    14         if(!rd[i])q.push(i);
    15     while(!q.empty()){
    16         int x=q.front();q.pop();
    17         a[++cnt]=x;
    18         for(int i=head[x];i;i=next[i])
    19             if(--rd[ver[i]]==0)q.push(ver[i]);
    20     }
    21 }
    22 
    23 int main()
    24 {
    25     cin>>n>>m; //n个点m条边
    26     for(int i=1;i<=m;i++){
    27         int x,y;
    28         scanf("%d%d",&x,&y);
    29         add(x,y);
    30     }
    31     bfs();
    32     for(int i=1;i<=cnt;i++)printf("%d ",a[i]);
    33     return 0;
    34 }

     

  • 相关阅读:
    稀疏自编码器一览表
    ZOJ 3886 Nico Number(筛素数+Love(线)Live(段)树)
    K好数(DP)
    【BZOJ4025】二分图
    又一次认识java(七) ---- final keyword
    二分查找
    从朴素贝叶斯分类器到贝叶斯网络(下)
    最近感到深深的绝望,感觉自己太菜了
    leetcode No.19 删除链表的倒数第N个节点 (python3实现)
    leetcode No.94 二叉树的中序遍历 (python3实现)
  • 原文地址:https://www.cnblogs.com/five20/p/8540737.html
Copyright © 2011-2022 走看看