一、拓扑排序(TopologicalSort)
所谓拓扑排序,就是指在一个有向无环图中,每个顶点都有出现的顺序,然后使得每个顶点都能出现。这里顶点可以看成是一个活动。
比如说我们要准备学校的运动会
首先我们要干嘛。。。
其次我们才能干嘛。。
。。。。。。。。。。
。。。。。。。。。。
最后我们才能干嘛
为了解决这类问题,于是拓扑排序就产生了。
二、基本思想
比如说一条边(v1,v2),我们要先进行v1这个活动,然后进行v2这个活动,那么此时v1的入度为0,v2的入度为1,我们要首先输出v1,然后v2的入度为0了,就可以输出了。
于是乎,就总结除了一条规则,首先找到入度为0的点,就如队列,然后把以入度为0的点作为弧尾的边删除,也就是把以v1为弧尾的点的入度减1,因为我们要删除这几条边对吧?、
我这里是用邻接表实现的
三、代码实现
1 #include "bits/stdc++.h" 2 using namespace std; 3 int indegree[110]; 4 int n,m; 5 list <int> adj[110];//创建邻接表 时间复杂度为O(v + e) v是定点数,e是边数 6 void Topological_Sort() 7 { 8 int cnt = 0; 9 queue <int> ans; 10 for(int i = 1;i <= n;i++)//把入度为0的加入队列 11 if(!indegree[i]) 12 ans.push(i); 13 while(!ans.empty()) { 14 int v = ans.front(); 15 ans.pop(); 16 cout << v << "-->";//输出入度为0的点 17 cnt++; 18 for(auto iter = adj[v].begin();iter != adj[v].end();iter++)//遍历一v为弧尾的边,并减去对应顶点的入度,把入度为0的加入队列 19 if(!(--indegree[*iter])) 20 ans.push(*iter); 21 } 22 if(cnt < n) 23 cout << "\nLoop!" << endl; 24 else 25 cout << "\nSuccessful!" << endl; 26 } 27 int main() 28 { 29 cin >> n >> m; 30 for(int i = 1;i <= m;i++){ 31 int sx,sy; 32 cin >> sx >> sy; 33 indegree[sy]++;//sy入度+1 34 adj[sx].push_back(sy); 35 } 36 Topological_Sort(); 37 return 0; 38 } 39 /* 40 test case: 41 6 6 42 6 3 43 6 1 44 5 1 45 5 2 46 3 4 47 4 2 48 动图网址:https://www.cs.usfca.edu/~galles/visualization/TopoSortIndegree.html 49 */