拓扑排序这种新手算法,在一年前我就已经系统地学过,但由于各种各样的原因,我不是很理解。在最近的比赛中,又遇到了一道拓扑排序题,尽管我运用堆勉强解决,但还是很不甘心,所以今天来复习一下拓扑排序。
先来说说拓扑排序是什么。虽然名字叫排序,但拓扑排序却不是我们平常说的排序。对于一个有向无环图G=(V,E)来说,其拓扑排序是其所有结点的一种线性次序,该次序满足如下条件:如果图G包含边(u,v),则节点u在拓扑排序中处于节点v的前面(如果图中包含环路,则不可能拍出一个线性次序)。因此,我们可以将图的拓扑排序看作是图的所有节点在一条水平线上排开,所有有向边都从左指向右。
明白了拓扑排序的定义,实现就很容易了。对于一个有向无环图G=(V,E),我们所需的时间复杂度就是O(V+E),V是点数,E是边数。我们可以从任意一个节点开始,dfs一次,然后,维护一个队列,当当前搜索到的点没有其他未经过的点相邻时,我们就可以将它放入队尾,最后输出队列就行了。
代码如下:
#include<iostream>
#include<cstdio>
using namespace std;
int n,m,u,v,tot,k;
int f[200001][3],q[100001],ans[100001];
bool bz[200001];
void dfs(int x)
{
printf("%d\n",x);
for (int i=q[x];i;i=