拓扑排序

简介: 拓扑排序

拓扑排序是针对有向无环图的,当然也可以用它来检测到底有没有环,数据结构中学过其构成原理,这里就不再赘述,主要来讲他的实现。

分析原理,其实他的过程有点类似于层次遍历,所以用队列存储入度为0的点是OK的,但其实只要每次入队的结点入度为0,也没有顺序要求,栈也行,这里我为了避免每次比较麻烦,直接用优先队列实现。


#include<iostream> 
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
int G[51][51];
int indegree[51]={0};
int num[51];//存储拓扑排序顺序
struct cmp{
  bool operator()(const int a,const int b)const{
  return indegree[a]>indegree[b];}
};
bool topologicalsort(int n){
  priority_queue<int,vector<int>,cmp>q; 
  //优先队列存储入度下标,按从小到大排序
  for(int i=1;i<=n;i++)//全部入队
  q.push(i);
  int i=1;
  while(!q.empty()){ //只要队空,拓扑完成
    int t=q.top();q.pop();
    if(indegree[t]!=0)//队首元素入度不为0,失败
    return false;
    num[i++]=t;
    for(int j=1;j<=n;j++) 
    if(G[t][j]!=0)
    indegree[j]--;
  }
   return true;
}
int main(){
  int n,x;
  scanf("%d",&n);
  for(int i=1;i<=n;i++)
  for(int j=1;j<=n;j++)
  {
    scanf("%d",&x);
    G[i][j]=x;
    if(x!=0)indegree[j]++;
  }
  if(topologicalsort(n)){
    for(int i=1;i<=n;i++)
    printf("%d ",num[i]-1) ;
    printf("\n");
  }
  else printf("ERROR");
  return 0;
}

而用栈实现拓扑排序有一个好处,其元素的输出恰好是逆拓扑排序,在求关键路径时有用,下面是其代码。

stack<int>s;//存储拓扑排序,逆向输出为逆拓扑排序
bool topological(int n) {
  queue<int>q;
  for(int i=1;i<=n;i++) 
  if(indegree[i]==0)
  q.push(i);
  while(!q.empty()){
    int t=q.front();q.pop();
      s.push(t);
      for(int i=0;i<Adj[t].size();i++){
        int x=Adj[t][i].v,w=Adj[t][i].w;
        indegree[x]--;
        if(indegree[x]==0)
        q.push(x);
    }
  }
  if(s.size()==n)return true;
  return false;
}
相关文章
|
8月前
拓扑排序
拓扑排序
51 0
|
8月前
|
存储 人工智能 算法
【算法总结】拓扑排序
【算法总结】拓扑排序
79 0
|
搜索推荐
|
人工智能 自然语言处理 搜索推荐
拓扑排序算法
拓扑排序算法
139 0
|
存储 算法 Java
【数据结构与算法】有向图的拓扑排序
【数据结构与算法】有向图的拓扑排序
222 1
【数据结构与算法】有向图的拓扑排序
拓扑排序(邻接表实现)
拓扑排序(邻接表实现)
202 0
拓扑排序(邻接表实现)
|
机器学习/深度学习 存储
图的遍历 无向图深搜 宽搜
图的遍历 无向图深搜 宽搜
图的遍历 无向图深搜 宽搜
拓扑排序-Kitchen Plates
J. Kitchen Plates time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard output
131 0
拓扑排序-Kitchen Plates
|
存储
拓扑排序讲解+例题
比如说给定若干个两个元素之间的大小关系,要转换成所有元素的总体大小关系,就可以用拓扑排序来处理 下面给出的例题就是这个样子 关于拓扑排序还有一种用法->判断给定的有向图中是否存在环 下面来说明一下拓扑排序的相关步骤: (默认已经将图存好)首先统计所有点的入度,然后将所有点入度为0的所有点放进队列(根据题目特殊要求也可以使用优先队列) 然后采取像BFS那样的方式,当队列非空的时候,始终取队列头端的一个元素,并将这个元素记录下来之后pop掉,把这个点(比如说是点P)放进用来存储拓扑序列的不定长数组vector中,然后遍历和这个点相连的所有点,并将与点P相连的所有点的入度减少1
135 0