图的一些相关概念

https://www.paincker.com/graph-theory/

图的拓扑排序

  • 什么是拓扑排序呢,简单来说就是进行逻辑上的排序,我们有一个先后顺序,要完成一个点,要把该节点的所有前置节点都完成
    https://zhuanlan.zhihu.com/p/127137701
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
using namespace std;

int n;  //边的数量
int m;  //顶点的数量 
vector<vector<int>> graph;  //邻接表存图
vector<int> ans; 
vector<int> in;

void topo_sort(){
    //我们现在知道的已知条件是知道了一个邻接表graph,我们需要把每一个节点的进度累加出来
	for(int i = 1; i <= m; i++){
		for(auto j : graph[i]){
			in[j]++;
		}
	}
	queue<int> q;
    //把一开始进度是零的节点放进队列
	for(int i = 1; i <= m; i++){
		if(in[i] == 0){
			q.push(i);
			ans.push_back(i);
		}
	}

	while(!q.empty()){
		int temp = q.front();
		q.pop();
        //把该节点的对应是哪几个节点的进度找出来并给他减去一
		for(auto i : graph[temp]){
			in[i]--;
            //减完之后的节点如果出现0,那么把他继续进队列之中重复操作
			if(in[i] == 0){
				q.push(i);
				ans.push_back(i);
			}
		}
	}
	
}
/*
    输入是:
    5 7 //表示的是有五个节点,有七个关系
    1 2
    1 3
    2 3
    2 4
    3 4
    3 5
    4 5
*/
int main()
{
    system("chcp 65001");
	cin >> m >> n;
	in.resize(m + 1, 0);
    //把邻接表初始化成大小是m+1的个数
	graph.resize(m + 1);
    //图的邻接表存储
	for(int i = 0; i < n; i++){
		int a, b;
		cin >> a >> b;
		graph[a].push_back(b);
	} 
    //进行拓扑排序
	topo_sort();
    //如果出来的结果数组的大小是m的话,那么说明没有逻辑循环
	if(ans.size() == m){
        cout << "拓扑排序成功,没有逻辑上的死循环" << endl;
		for(auto i : ans){
			cout << i <<" ";
		}
	}
	else{
		cout << "有环" <<endl; 
	} 
	return 0;
}

posted @ 2023-08-18 16:08  铜锣湾陈昊男  阅读(6)  评论(0)    收藏  举报