首先,什么是拓扑序列?
拓扑序列是顶点活动网中将活动按发生的先后次序进行的一种排列。. 拓扑排序,是对一个有向无环图 (Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边 (u,v)∈E (G),则u在线性序列中出现在v之前。. 通常,这样的线性序列称为满足拓扑次序 (Topological Order)的序列,简称拓扑序列。. 简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。
那什么叫入度为零呢?
当入度为 0 时,指有向图中的点不作为任何边的终点,也就是说,这一点所连接的边都把这一点作为起点。 在有向图的 拓扑排序 中,每次都选取入度为 0 的点加入拓扑队列中,再删除与这一点连接的所有边。
拓扑序列保存?
可以建很多链表,每个链表保存一条路径,在表头可以随便插入数据。
下面看例题;
给定一个 n 个点 m 条边的有向图,点的编号是 1 到 n,图中可能存在重边和自环。
请输出任意一个该有向图的拓扑序列,如果拓扑序列不存在,则输出 −1。
若一个由图中所有点构成的序列 A 满足:对于图中的每条边 (x,y),x 在 A 中都出现在 y 之前,则称 A 是该图的一个拓扑序列。
输入格式
第一行包含两个整数 n 和 m。
接下来 m 行,每行包含两个整数 x 和 y,表示存在一条从点 x 到点 y 的有向边 (x,y)。
输出格式
共一行,如果存在拓扑序列,则输出任意一个合法的拓扑序列即可。
否则输出 −1。
数据范围
1≤n,m≤105
输入样例:
3 3
1 2
2 3
1 3
输出样例:
1 2 3
第一步,建立链表存储
第二步,找到入度为零的点;
第三步,依次遍历,把当前的数据放进队列中,队列中元素出队列顺序就是拓扑顺序,当然,答案可能有很多种哦。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int e[N],ne[N],h[N],idx,d[N],top[N],cnt;
int a,b;
void add(int a,int b)
{
e[idx]=b;
ne[idx]=h[a];
h[a]=idx++;
}
bool topsort()
{
queue<int>r;
for(int k=1;k<=a;k++)
{
if(d[k]==0)
r.push(k);
}
int t;
while(!r.empty())
{
t=r.front();
top[cnt]=t;
cnt++;
r.pop();
for(int k=h[t];k!=-1;k=ne[k])
{
int j=e[k];
d[j]--;
if(d[j]==0) r.push(j);
}
}
if(cnt<a-1) return 0;
else return 1;
}
int main()
{
cin>>a>>b;
memset(h,-1,sizeof(h));
for(int k=1;k<=b;k++)
{
int c,e;
cin>>c>>e;
add(c,e);
d[e]++;
}
if(topsort()==0) cout<<"-1";//没有
else //有
{
for(int k=0;k<a;k++)
{
cout<<top[k]<<" ";
}
}
return 0;
}