拓扑排序(DGA)——有向无环图
拓扑排序基本操作
/*
-------------------------------------------------
Author: wry
date: 2022/2/27 10:16
Description: DAG
-------------------------------------------------
*/
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1000+10;
vector<int> graph[MAXN]; //用向量构造邻接表
int inDegree[MAXN]; //每个点的入度
vector<int> DGA(int n) { //n个点
vector<int> dga;
priority_queue<int,vector<int>,greater<int>> node; //待处理的入度为0的小根堆,先输出的是编号小的
for (int i=0;i<n;i++) { //需注意有的题目编号是1~n
if (inDegree[i]==0) { //如果入度为0
node.push(i);
}
}
//以第一轮处理的结果开始进行后序处理
while (!node.empty()) {
int u = node.top();
node.pop();
dga.push_back(u); //将此点编号压入拓扑序列中
for (int i=0;i<graph[u].size();i++) {
inDegree[graph[u][i]]--; //u指向的点的入度--
if (inDegree[graph[u][i]]==0) {
node.push(graph[u][i]);
}
}
}
return dga;
}
int main() {
int n,m;
while (cin>>n>>m) {
memset(graph,0,sizeof(graph));
memset(inDegree,0,sizeof(inDegree));
//构造图
while (m--) {
int from,to;
cin >> from >> to;
graph[from].push_back(to); //拓扑排序是有向无环图
inDegree[to]++;
}
//拓扑序列
vector<int> dga = DGA(n); //传入顶点数
for (int i=0;i<dga.size();i++) {
printf ("%d ",dga[i]);
}
}
return 0;
}
Note:
1. memset(graph,0,sizeof(graph));
memset(inDegree,0,sizeof(inDegree));
表示向量和数组都可以用memset函数进行初始化。
2. 邻接表常用于构建图
3. 拓扑排序中需要有记录各个点的入度信息的数组inDegree[]。