拓扑排序(搜索) 算法具体步骤如下:
1、 调用toposort();
2、 在toposort()每次调用dfs()的过程中,都记录了顶点u的完成时间,将顶点u按完成顺序保存在存放拓扑排序顺序的数组topo[]中。这样,该数组就存放了按先后顺序访问完成的所有顶点。
3、 最后拓扑排序得到的线性序列,即为topo[]的逆序。
bool visit[maxn];
int topo[maxn], t;
bool dfs(int u){
visit[u] = -1; //-1表示正在被访问
for(int v=0; v<n; v++)
if(G[u][v]){
if(visit[v]<0) return false; //存在有向环,失败退出
else if(!visit[v] && !dfs(v)) return false; //访问下一个结点
}
visit[u]=true;
topo[--t]=u;
return true;
}
bool toposort(){
t=n;
memset(visit, 0, sizeof(visit));
for(int u=0; u<n; u++)
if(!visit[u] && !dfs(u)) return false;
return true;
}
2.拓扑排序(出度算法)
算法步骤:
(1)从有向图中选择一个没有前驱(入度为0)的顶点并且输出它
(2)从图中删除该结点,并且删除从该顶点发出的全部有向边
(3)重复上述两步,直到剩余的图中不再存在没有前驱结点为止
//用链式前向星储存整张图,再开一个额外数组储存每个节点的入度,每删除一个点,就遍历以这个点为起点的边,将对应边的终点入度减1即可选择并删除下一个点
#include<bits/stdc++.h>
using namespace std;
int queue[maxn];
int m=1;
for(int i=1; i<=n; i++)
if(indegree[i]==0)//入度为0
queue[m++]=i;
//使用队列中的点更新ingree数组并生成拓扑序列
for(int i=1; i<m; i++)
{
//删除从该顶点发出的全部有向边,更新indegree数组
int tmp;
tmp=queue[i];
for(k=head[tmp]; k!=-1; k=Edge[k].next)
{
indegree[Edge[k].to]--;
if(indegree[Edge[k].to]==0)//说明该点已经没有前驱,入度为0
queue[m++]=Edge[k].to; //加入队列
}
}
//输出
for(int i=1; i<m; i++) cout<<queue[i]<<' ';
cout<<endl;