拓扑排序就是把一个图的所有节点排序,使得每一条有向边(u,v)对应的u都排在v的前面。
拓扑排序的一个用途就是判断一个有向图是否有环。
性质
1、拓扑排序在有向无环图中才能排出有效的序列,否则能判断该有向图有环。
2、如果输入的有向图中的点,不存在入度为0的点,则该有向图存在回路
3、如果存在的入度为0的点大于一个,则该有向图肯定不存在一个可以确定的拓扑序列但并不妨碍拓扑排序
拓扑排序还有一个重要的功能就是判断节点是一条链,还是在某个节点出现了分叉。
拓扑排序的链式前向星实现:
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
const int N = 10005;
bool vis[N];
int head[N],degree[N];
int Q[N],cnt,num;
struct EdgeNode
{
int to;
int next;
};
EdgeNode Edge[N];
void Init()
{
cnt = 0;
memset(vis,false,sizeof(vis));
memset(head,-1,sizeof(head));
memset(degree,0,sizeof(degree));
}
void add(int u,int v)
{
degree[v]++;
Edge[cnt].to = v;
Edge[cnt].next = head[u];
head[u] = cnt++;
}
void TopSort(int n)
{
num = 0;
for(int i=1;i<=n;i++) //先将没有前驱的节点加入队列
if(!degree[i]&&vis[i])
Q[num++] = i;
for(int i=0;i<num;i++)
{
//删除从该节点出发的所有边,更新degree数组
for(int k = head[Q[i]];k != -1;k = Edge[k].next)
{
degree[Edge[k].to]--;
//如果degree数组为0,说明新的没有前驱的节点找到,加入队列中
if(!degree[Edge[k].to])
Q[num++] = Edge[k].to;
}
}
}
int main()
{
int n,m;
while(cin>>n>>m)
{
Init();
while(m--)
{
int x,y;
cin>>x>>y;
vis[x] = true;
vis[y] = true;
add(x,y);
}
TopSort(n);
for(int i=0;i<num;i++)
cout<<Q[i]<<" ";
cout<<endl;
}
return 0;
}
本文介绍了拓扑排序的概念及其在有向无环图中的应用,并提供了一种基于链式前向星的数据结构实现方法。文中详细解释了如何通过拓扑排序来判断图中是否存在环,并展示了完整的C++代码实现。
888

被折叠的 条评论
为什么被折叠?



