什么是拓扑排序呢?他又是用来干嘛的?
生活中,我们经常面临这样的情况:几件事情之间有相互依赖关系,必须其中的几件发生,某件才能发生。我们可以用有向无环图来表示这种关系,一个点指向另一个点代表该点要先于另一点。注意一定是没有环的,否则就进入了无休止的死循环。。。
这样,每个点的入度代表该点先前的点数,任意时刻入度为0的点就是可以访问的点。每次访问一点并将其从图中删除,对应的点入度减1,不断重复这个过程,知道所有的点都被遍历,这就叫拓扑排序。特别的,点的访问顺序叫做拓扑序,一个DAG可能有多个拓扑序。
1 int ans[maxn],cnt; 2 queue<int> q; //队列用于存放入度为0的点 3 struct edge { //邻接表存储图 4 int v,next; 5 } E[maxm]; 6 void topo_sort() { 7 for(int i=1;i<=n;++i) if(!ind[i]) q.push(i); //先将入度为0的点入队 8 while(!q.empty()) { 9 int u=q.front();q.pop(); 10 ans[++cnt]=u; //记录拓扑序,通过cnt是否等于n还可判断是否存在拓扑序 11 for(int p=head[u];p+1;p=E[p].next) //删边,该点指向的点的入度减1,同时将新的入度为0的点入队 12 if(!(--ind[E[p].v])) q.push(E[p].v); 13 } 14 }