848. 有向图的拓扑序列(拓扑排序模板题)

发布时间:2024年01月10日

848. 有向图的拓扑序列 - AcWing题库

给定一个?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

解析 :

拓扑排序的删边环节不需要真的将边给删除,只需要将入读减去 1 即可,入度为零的边则加入队列中。

当无法进行拓扑排序时,比如说有环时,加入过队列的点的数量就会小于图中点的数量

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>
#include<sstream>
#include<deque>
#include<unordered_map>
using namespace std;
typedef pair<double, int > PDI;
typedef pair<int, int> PII;
const int N = 1e5 + 5, M = 1e5 + 5;
int n, m;
int h[N], e[M], ne[M], idx;
int q[N], d[N];

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

int topsort() {
	int hh = 0, tt = 0;
	for (int i = 1; i <= n; i++) {
		if (!d[i])q[tt++] = i;
	}
	while (hh != tt) {
		int t = q[hh++];
		for (int i = h[t]; i != -1; i = ne[i]) {
			int j = e[i];
			if(d[j])d[j]--;
			if (!d[j]) {
				q[tt++] = j;
			}
		}
	}
	return tt == n ;
}


int main() {
	scanf("%d%d", &n, &m);
	memset(h, -1, sizeof h);
	for (int i = 1,a,b; i <= m; i++) {
		scanf("%d%d", &a, &b);
		add(a, b);
		d[b]++;
	}

	if (topsort()) {

		for (int i = 0; i < n; i++) {
			printf("%d ", q[i]);
		}
		cout << endl;
	}
	else {
		cout << -1 << endl;
	}

	return 0;
}

文章来源:https://blog.csdn.net/Landing_on_Mars/article/details/135506355
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。