考研机试:拓扑排序

版权声明:本博全为博主学习日常,均为原创,请勿转载 https://blog.csdn.net/weixin_44332298/article/details/88076147
//拓扑排序  邻接链表 
#include <iostream>
#include <vector> //模板 
#include <queue> //模板 
using namespace std;

vector<int> edge[501];
queue<int> Q;

int main(){
	int n, m;
	int degree[501]; //入度  拓扑排序判断的是入度,与出度没有关系 
	while(cin >> n >> m){//n个节点m条边 
		for(int i = 0; i < 501; i++){ //初始化 
			degree[i] = 0;
			edge[i].clear();
		} 
		while(Q.empty() == false){ //队列初始化 
			Q.pop(); //弹出Q中元素,直到Q为空 
		}
		
		while(m--){
			int a, b;
			cin >> a >> b; //输入a->b的一条边 
			degree[b]++;
			edge[a].push_back(b);
		}
		
		for(int i = 1; i <= n; i++){ //找入度为0的节点,找到后放入队列 
			if(degree[i] == 0){
				Q.push(i);
			}
		} 
		while(Q.empty() == false){ //队列中还有元素时 
			int now = Q.front(); //访问队头元素
			Q.pop(); 
			cout << now << " ";
			
			for(int k = 0; k < edge[now].size(); k++){
				degree[edge[now][k]]--; //now节点已经出队, 入度要减一 
				if(degree[edge[now][k]] == 0)
					Q.push(edge[now][k]); 
			}
		} 
		cout << endl;
	}
	return 0;
}

排序时优先排序号小的。

//拓扑排序  邻接链表 
#include <iostream>
#include <vector> //模板 
#include <queue> //模板 
using namespace std;

vector<int> edge[501];
queue<int> Q;
bool mark[501]; 

int main(){
	int n, m;
	int degree[501]; //入度  拓扑排序判断的是入度,与出度没有关系 
	while(cin >> n >> m){//n个节点m条边 
		for(int i = 0; i < 501; i++){ //初始化 
			degree[i] = 0;
			edge[i].clear();
			mark[i] = false;
		} 
		while(Q.empty() == false){ //队列初始化 
			Q.pop(); //弹出Q中元素,直到Q为空 
		}
		
		while(m--){
			int a, b;
			cin >> a >> b; //输入a->b的一条边 
			degree[b]++;
			edge[a].push_back(b);
		}
		
		/*for(int i = 1; i <= n; i++){ //找入度为0的节点,找到后放入队列 
			if(degree[i] == 0){
				Q.push(i);
			}
		} */
		
		for(int i = 1; i <= n; i++){ //找入度为0的节点,找到后放入队列 
			if(degree[i] == 0){
				Q.push(i);
				break; //保证编号小的节点先输出 
			}
		} 
		
		int flag = 0; //控制输出格式 
		while(Q.empty() == false){ //队列中还有元素时 
			int now = Q.front(); //访问队头元素
			Q.pop(); 
			mark[now] = true; //出队标记位设为true 
			if(flag == 0){
				cout << now;
				flag = 1;
			} 
			else{
				cout << " " << now;
			}
			
			
			for(int k = 0; k < edge[now].size(); k++){
				degree[edge[now][k]]--; //now节点已经出队, 入度要减一 
				//if(degree[edge[now][k]] == 0)
				//	Q.push(edge[now][k]); 
			}
			
			for(int i = 1; i <= n; i++){ //现根据题目规则,需要找编号小的入度为0的点 
				if(degree[i] == 0 && mark[i] == false){
					Q.push(i);
					break; //保证编号小的节点先输出 
				}
			} 
			
		} 
		cout << endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44332298/article/details/88076147
今日推荐