首页 > 代码库 > 拓扑排序

拓扑排序

了解拓扑排序,首先要知道几个概念:

拓扑:拓扑学(topology)是研究几何图形或空间在连续改变形状后还能保持不变的一些性质的学科。它只考虑物体间的位置关系而不考虑它们的形状和大小。

DAG:Directed Acyclic Graph 有向无环图。拓扑排序是在DAG的基础上进行的,而拓扑排序也可以判断一个图是否为DAG。

 

拓扑排序,通俗的说,就是有n个变量,并且m个二元组(u,v)代表u<v。拓扑排序要做的事情就是把它们从小到大排列起来。

算法实现基础:DFS

思路:

把每个元素看做一个点,“小于”关系看成一条有向边,现在要做的事情就是把节点排序,是每一条有向边(u,v)的u都排在v的前面。

(如果图中存在有向环,就不存在拓扑序)

Code:

技术分享
 1 #include<iostream> 2 using namespace std; 3 const int maxn=1010; 4 const int maxm=5010;  5 int n,m,t;                           //有n个点,m组二元组。  6 int a[maxn][maxn],c[maxn]; 7 int topo[maxn]; 8 void rd(){ 9     cin>>n>>m;    10     for (int i=1; i<=m; i++){11         int u,v;12         cin>>u>>v;          //u,v代表二元组(u,v),即u<v。 13         a[u][v]=1;    14     }15 }16 17 bool dfs(int u)18 {19     c[u]=-1;20     for (int v=1; v<=n; v++) if (a[u][v]){21         if (c[v]<0) return false;22         else if (!c[v] && !dfs(v)) return false;23     }24     c[u]=1; topo[--t]=u;25     return true;26 }27 28 bool solve(){29     t=n+1;    30     for (int i=1; i<=n; i++) if (!c[i])31       if (!dfs(i)) return false;32       return true;33 }34 35 int main(){36     rd();37     bool bb=solve();38     if (bb){39       cout<<"True"<<endl; 40       for (int i=1; i<=n; i++) cout<<topo[i]<<" ";41       cout<<endl;42     }43     else cout<<"False"<<endl;44     return 0;45 }
View Code

 

拓扑排序