#A. 拓扑排序模板题

    传统题 1000ms 256MiB

拓扑排序模板题

该比赛已结束,您无法在比赛模式下递交该题目。您可以点击“在题库中打开”以普通模式查看和递交本题。

题目描述

输入顶点和边数,以及顶点关系,对其进行拓扑排序。(按照栈的特性进行拓扑排序,初始时按照按照1~n的顺序将入度为0的点加入栈中,注意:本题存在重边)

输入格式

第一行输入顶点数v和边数e 接下去输入e行的边关系

输出格式

如果图中存在环,则输出 has circle,否则,输出它的拓扑顺序。

样例

输入样例

样例输入1

4 4
1 2
1 3
4 3
2 4

样例输出1

1 2 4 3

输入样例

样例输入2

3 3
1 2
2 3
3 1

样例输出2

has circle

数据范围与提示

1<=e,v<=100000

注释代码

#include<bits/stdc++.h>
using namespace std;

stack<int> s;   //存入度为0的点
int n, m;   //n个点,m条边
vector<int> v[100005];   //v[i]存储节点i的所有终点
int d[100005];   //d[i]表示i的入度大小
queue<int> q;
int main(){
	cin >> n >> m;
	for(int i=1; i<=m; i++){  //有m条边
		int x, y;   //x -> y   //表示x走到y
		cin >> x >> y;    
		d[y]++;   //y的入度+1
		v[x].push_back(y);    //x点的后面有一个终点y
	}
	//循环把区间[1, n]的点中入度为0的点加入栈s
	for(int i=1; i<=n; i++){
		if(!d[i]) s.push(i);  //i入度为0,加入栈 
	}
	
	//只要栈不为空,说明还有入度为0的点,说明还没有走完
	//所以从这个点出发继续尝试走
	while(s.size()){   
		int x = s.top();   //取出栈顶
		s.pop();   //把栈顶删除
		q.push(x); 
		//从x这个点出发,把所有的能走到的点y入度-1
		//如果y的入度-1之后变成了0,那么把y加入栈
		for(int y : v[x]){   //遍历x能走到的所有点y
			d[y]--;
			if(d[y] == 0) s.push(y);
		}
	}
	if(q.size() != n) cout << "has circle";  //如果队列里面的点数量不等于n,说明有环
	else{
		while(q.size()){
			cout << q.front() << ' ';
			q.pop();
		}
	}
	return 0;
}

【L2-第二十六课】-拓扑排序-2025.01.15

未认领
状态
已结束
题目
2
开始时间
2025-1-15 0:00
截止时间
2025-1-23 23:59
可延期
24 小时