拓扑排序(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[]。

posted @ 2022-02-27 10:45  火星架构师  阅读(467)  评论(0编辑  收藏  举报