拓扑排序

来源:互联网 发布:如何把淘宝网店做好 编辑:程序博客网 时间:2024/06/09 07:29

拓扑排序就是把一个图的所有节点排序,使得每一条有向边(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;}


 

原创粉丝点击