0
点赞
收藏
分享

微信扫一扫

拓扑序列例题

辰鑫chenxin 2022-02-15 阅读 44

题目:

给定一个n个点m条边的有向图,图中可能存在重边和自环。

请输出任意一个该有向图的拓扑序列,如果拓扑序列不存在,则输出-1。

若一个由图中所有点构成的序列A满足:对于图中的每条边(x, y),x在A中都出现在y之前,则称A是该图的一个拓扑序列。

输入格式

第一行包含两个整数n和m

接下来m行,每行包含两个整数x和y,表示点x和点y之间存在一条有向边(x, y)。

输出格式

共一行,如果存在拓扑序列,则输出拓扑序列。

否则输出-1。

数据范围

1≤n,m≤10^5
输入样例:

3 3
1 2
2 3
1 3

输出样例:

1 2 3

代码:

#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;
const int N=1e5+10;
int h[N],e[N],ne[N],idx,q[N],d[N],n,m,b[N];

void add(int a,int b){
	e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}

bool topsort(){
	int hh=0,tt=-1;//定义队头队尾 
	for(int i=1;i<=n;i++){
		if(!d[i]) q[++tt]=i;//取出所有入队为零的数存进q 
	}
	while(hh<=tt){
		int v=q[hh++];
		for(int i=h[v];i!=-1;i=ne[i]){
			int w=e[i];
			d[w]--;//取出一个数,入队减一 
			if(!d[w]) q[++tt]=w;//如果入队为零存入q 
		}
	}
	if(tt==n-1){
		for(int i=0;i<n;i++) cout<<q[i]<<" ";
		cout<<endl;
	}
}

int main(){
	cin>>n>>m;
	memset(h,-1,sizeof h);
	for(int i=0;i<m;i++){
		int a,b; 
		cin>>a>>b;
		add(a,b);
		d[b]++;
	}
	topsort();
	return 0;
}
举报

相关推荐

0 条评论