码迷,mamicode.com
首页 > 编程语言 > 详细

拓扑排序的两种实现--基于dfs和基于入度

时间:2015-07-20 16:42:50      阅读:463      评论:0      收藏:0      [点我收藏+]

标签:拓扑排序

#include <cstdio>
#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>

using namespace std;
int n;
vector<int> vec[100];





int vis[100];
struct node{
	int n;
	int t;
	bool operator  < (const node& a)const {
		return t > a.t;
	}
};
node et[100];
int tm = 0;
/*
	基于dfs的拓扑排序,利用dfs中的完成时间戳,完成时间戳越大越放在前面 
*/
bool dfs(int x){
	tm ++;
	vis[x] = 1;
	int si = vec[x].size();
	for(int i = 0;i < si;i++){
		int v = vec[x][i];
		if(vis[v] == 1){
			return false; 
		}
		else if(vis[v] == 0){
			if(!dfs(v)){
				return false;
			}	
		}
	}
	tm ++;
	et[x].t = tm;
	vis[x] = 2;
}

int topu_DFS(){
	tm = 0;
	memset(vis,0,sizeof(vis));
	for(int i = 0;i < n;i++){
		et[i].n = i;		
	}
	for(int i = 0;i < n;i++){
		if(!vis[i]){
			if(!dfs(i)){
				printf("no order!!!!\n");
			}
		}	
	}
	sort(et,et+n);
	
	for(int i = 0;i < n;i++){
		printf("%d ",et[i].n);
	}
}

/*
	基于入度的拓扑排序 
*/ 
int d[100];
int topu_rudu(){
	stack<int> st;
	
	for(int i = 0;i < n;i++){
		d[i] = vec[i].size();
		if(d[i] == 0){
			st.push(i);
		}
	}
	queue<int> que;
	
	while(!st.empty()){
		int u = st.top();
		st.pop();
		que.push(u);	
		int si = vec[u].size();
		for(int i = 0;i < si;i++){
			int v = vec[u][i];
			d[v]--;
			if(d[v] == 0){
				st.push(v);
			}
		}
	}
	if(que.size()!=n){
		printf("no order!!!\n");
	}
	else{
		while(!que.empty()){
			printf("%d ",que.front());
			que.pop();
		}
	}
} 
int main(){
	while(cin >> n){
		int m;
		cin >> m;
		for(int i = 0;i < m;i++){
			int x,y;
			
			cin >> x >> y;
			vec[x].push_back(y);	
		}
		topu_rudu();
		topu_DFS();
		
	}
} 

版权声明:本文为博主原创文章,未经博主允许不得转载。

拓扑排序的两种实现--基于dfs和基于入度

标签:拓扑排序

原文地址:http://blog.csdn.net/qq_24667639/article/details/46967929

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!