拓扑排序并且输出一个可能的序列

如题描述:根据给出的图输出一个可能的拓扑序列。判断能否进行拓扑排序的关键是图是否存在环。

这里我们用数组c的值表示顶点当前的状态。0代表没有被访问过,-1代表正在被访问,1代表该点及其子孙均被访问过,并且是不存在的环的点。那么我们用dfs去遍历,如果该点在被访问的过程中再次被访问,则证明存在环。或者该点没有被访问过但是在递归访问它的后继元素时存在环,也是返回失败。

看代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define INF 100000000;
using namespace std;
const int maxn = 10000 + 5;
int mp[maxn][maxn];
int c[maxn],topo[maxn],t,n;
bool dfs(int u) {
	c[u] = -1;//正在访问该顶点 
	for(int v = 0; v < n; v++) {
		if(mp[u][v])
			if(c[v] < 0) return false;//绕了一圈又回来,即存在有向环,不能拓扑 
			else if(!c[v]&&!dfs(v)) return false;//该点的子孙存在环 
	}
	c[u] = 1;//已经访问过该点及其子孙,并且已返回 
	topo[--t] = u;//存储拓扑序列,倒着存储,便于正着打印 
	return true;
}
bool toposort() {
	t = n;
	memset(c,0,sizeof(c));
	for(int u = 0; u < n; u++)
		if(!c[u])
			if(!dfs(u))
				return false;
	return true;
}

int main() {
	int e,x,y,t;
	cin>>e>>n;
	for(int i = 0; i < e; i++) {//建图 
		cin>>x>>y;
	   	mp[x][y] = 1;
	}
	cout<<toposort()<<endl;//是否能进行拓扑排序 
	for(int i = 0; i < n; i++)
		cout<<topo[i];//打印拓扑序列 
	cout<<endl;
	return 0;
}

    原文作者:拓扑排序
    原文地址: https://blog.csdn.net/JingleLiA/article/details/80626542
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞