前言:巩固基础,发一发拓扑排序的理解。
定义:
在一个有向无环图中,若存在一个由图中的某些点所构成的序列A,满足:对于任意边(x,y),x在A中都出现在y之前,则A是该有向无环图顶点的一个拓扑序。求解序列A的过程即拓扑排序。
实现思想:
拓扑排序的思路实际很容易。因为拓扑序的性质是要满足边(x,y)中x出现在y之前,所以一个点若要加入拓扑序列中,则必须保证连向它的点都在它之前出现在该序列中,于是大致思路便有了,建立空队列,直接统计所有点的入度,然后将所有入度为0的点放入队列,取出队首并将其所连向的点的入度减1,不停判断入度为0的点并重复上述步骤,直到不存在入度为0的点为止(队列为空)。
代码:
1 #include<bits/stdc++.h> 2 #define il inline 3 using namespace std; 4 const int N=10005,M=100005; 5 int n,m,a[N],tot,cnt,ver[M],next[M],head[N],rd[N]; 6 il void add(int x,int y) //邻接表加有向边 7 { 8 ver[++tot]=y,next[tot]=head[x],head[x]=tot; 9 rd[y]++; 10 } 11 il void bfs(){ //拓扑排序用队列实现 12 queue<int>q; 13 for(int i=1;i<=n;i++) 14 if(!rd[i])q.push(i); 15 while(!q.empty()){ 16 int x=q.front();q.pop(); 17 a[++cnt]=x; 18 for(int i=head[x];i;i=next[i]) 19 if(--rd[ver[i]]==0)q.push(ver[i]); 20 } 21 } 22 23 int main() 24 { 25 cin>>n>>m; //n个点m条边 26 for(int i=1;i<=m;i++){ 27 int x,y; 28 scanf("%d%d",&x,&y); 29 add(x,y); 30 } 31 bfs(); 32 for(int i=1;i<=cnt;i++)printf("%d ",a[i]); 33 return 0; 34 }