拓扑排序【入门】

参看资料:

https://blog.csdn.net/lisonglisonglisong/article/details/45543451

https://blog.csdn.net/qq_41713256/article/details/80805338


什么是拓扑排序:

       在图论中,拓扑排序(Topological Sorting)是一个有向无环图(DAG, Directed Acyclic Graph)的所有顶点的线性序列。且该序列必须满足下面两个条件:

        1》每个顶点出现且只出现一次。
        2》若存在一条从顶点 A 到顶点 B 的路径,那么在序列中顶点 A 出现在顶点 B 的前面
        PS:有向无环图(DAG)才有拓扑排序,非DAG图没有拓扑排序一说。
 

对图进行拓扑排序:

        在一个有向图中,对所有的节点进行 排序,要求:没有一个节点指向它前面的节点。

        1》先统计所有节点的入度,对于入度为0的节点就可以分离出来,然后把这个节点指向的节点的入度减一。

        2》一直做改操作,直到所有的节点都被分离出来。

        3》如果最后不存在入度为0的节点,那就说明有环不存在拓扑排序,也就是很多题目的无解的情况。

        例:

          

实现代码:

        1》效率较低,但易于理解:

//b[]为每个点的入度
for(i=1;i<=n;i++){
   for(j=1;j<=n;j++){
      if(b[j]==0){   //找到一个入度为0的点
        ans=j;       //标记该点
        vis[cnt++]=j;//将该点放入目标序列
        b[j]--;      //将该点入度改为-1,表示该点不存在
        break;
       }
    }
    for(j=1;j<=n;j++)
        if(a[ans][j]) b[j]--; //与入度为0的点ans相连的点的入度减一
}
    printf("%d",vis[0]);
    for(i=1;i<cnt;i++) printf(" %d",vis[i]);    //输出目标序列
    printf("\n");

          2》效率较高,也挺好理解【看注释老弟】:

queue<int>q;
for(int i=0;i<n;i++)         //n  节点的总数
    if(in[i]==0) q.push(i);  //将入度为0的点入队列

vector<int>ans;              //ans 为拓扑序列
while(!q.empty()){
    int p=q.top();
    q.pop();          // 选一个入度为0的点,出队列
    
    ans.push_back(p); //将该度数为零的点放入目标队列
    
    for(int i=0;i<edge[p].size();i++){  //枚举与该度数为0的点想连的节点
        int y=edge[p][i];
        in[y]--;      //入度减1
        
        if(in[y]==0)  //若得到一个入度为0的点,将其放入度数为0的队列
        q.push(y);  
    }
}
if(ans.size()==n){    //所有的点都进入了拓扑序列
    for(int i=0;i<ans.size();i++)
        printf( "%d ",ans[i] );
    printf("\n");
}
else printf("No Answer!\n");   //  ans 中的长度与n不相等,就说明无拓扑序列

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值