浅谈拓扑排序(DFS学习)
给定一张有向无环图
若一个由图中所有点构成的序列A满足:对于图中每条边(x,y),x在A中都出现在A之前,则称A是该有向无环图顶点的一个拓扑序。
求解序列A的过程就成为拓扑排序。
拓扑排序过程的思想非常简单,我们只需要不断选择图中入度为0的节点x,然后把x连向的点入度减1。
广搜过程实现(DFS):
1.建立空的拓扑序列A。
2.预处理出所有点的入度deg[i],起初把所有入度为0的点入队。
3.取出队头节点x,把x加入拓扑序列A的末尾。
4.对于从x出发的每条边(x,y),把deg[y]减1。若被减为0,则把y入队。
5.重复3~4步直到队列为空,此时A即为所求
PS:如序列A的长度小于图中节点数量,则说明某些节点未被遍历,即图中存在环。
具体(部分)代码实现:
void add(int x,int y)//在邻接表中添加一条有向边
{
ver[++tot]=y;
next[tot]=head[x];
head[x]=tot;
deg[y]++;
return;
}
void topsort()//拓扑排序
{
queue<int> q;
for(int i=1;i<=n;i++)
{
if(deg[i]==0) q.push(i);
}
while(q.size())
{
int x=q.front();
q.pop();
a[++cnt]=x;
for(int i=head[x];i;i=next[i])
{
int y=ver[i];
if(--deg[y]==0) q.push(y);
}
}
return;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
}
topsort();
for(int i=1;i<=n;i++)
{
printf("%d",a[i]);
}
return 0;
}
Orz