拓扑排序的英文名是 Topological sorting。
拓扑排序要解决的问题是给一个图的所有节点排序。
在生活中,当我们想要做一件事情的时候,常常会发现如果想要完成这件事,需要许多其他的事做准备,比如做饭之前,你需要买菜,洗菜,切菜,而再切菜之前,你还得先有一把刀,一个菜板等等。拓扑排序就是让我们将这一系列的事按照我们想要的顺序排列起来。
我的常用方法叫做Kahn 算法,它的核心思想是永远维持一个入度为0的顶点。
伪代码如下
int map[M][M],in[M];//map用来记录从前到后的连线,此处用bool也可,in表示当前点的入度
int n,m;
void Topu()
{
int i,j,k=0;
for(i=1; i<=m; i++)
{
if(in[i]==0)//如果当前点的入度为0,则将其放入队列
{
q.push(i);
in[i]--;//使其入度为负,避免重复读入,不要也可。
}
}
while(!q.empty())
{
int p=q.top();//取出第一个元素
q.pop();//扔掉第一个元素
for(i=1; i<=m; i++)
{
if(map[p][i]!=0)//如果当前点与取出的元素之间有关系(也就是有连线)
{
in[i]--;//就将其入度-1
}
if(in[i]==0)//如果减一后入度为0
{
q.push(i);//将其放入队列
in[i]--;
}
}
}
}
int main()
{
int i,j,k;
scanf("%d %d",&m,&n)
memset(map,0,sizeof(map));
memset(in,0,sizeof(in));
for(i=0; i<n; i++)
{
scanf("%d %d",&j,&k);
if(!map[j][k])//如果两点之间还没有连线
{
map[j][k]=1;//就让其之间产生连线
in[k]++;//后者入度+1
}
}
Topu();
}