【每日算法】AB13 拓扑排序

简介: 【每日算法】AB13 拓扑排序

一、题目

描述

给定一个包含n个点m条边的有向无环图,求出该图的拓扑序。若图的拓扑序不唯一,输出任意合法的拓扑序即可。若该图不能拓扑排序,输出-1。

输入描述:

第一行输入两个整数n,m ( 1≤n,m≤2⋅10^5),表示点的个数和边的条数。接下来的mm行,每行输入两个整数ui,vi(1≤u,v≤n),表示ui到vi之间有一条有向边。

输出描述:

若图存在拓扑序,输出一行n个整数,表示拓扑序。否则输出-1。

二、代码

#include <stdio.h>
#include <stdlib.h>

// 图中节点的结构,分别为邻接点(表示为数组)、编号、入度、出度
typedef struct vNode{
    struct vNode** adj;
    int index;
    int inNum;
    int outNum;
}vNode;

int main() {
    int nodeNum, edgeNum;
    scanf("%d%d", &nodeNum, &edgeNum);
    int cover[nodeNum]; // i点是否已经被处理
    struct vNode* gragh[nodeNum];
    // 初始化图中节点
    for(int i = 0; i < nodeNum; i ++){
        gragh[i] = (struct vNode*)malloc(sizeof(struct vNode));
        gragh[i]->index = i;
        gragh[i]->inNum = 0;
        gragh[i]->outNum = 0;
        gragh[i]->adj = NULL;
        cover[i] = 0;
    }
    // 边的输入
    int v1, v2;
    for(int i = 0; i < edgeNum; i ++){
        scanf("%d%d", &v1, &v2);
        v1--;
        v2--;
        gragh[v2]->inNum ++;
        gragh[v1]->adj = realloc(gragh[v1]->adj, sizeof(struct vNode*) * (++ gragh[v1]->outNum));
        gragh[v1]->adj[gragh[v1]->outNum - 1] = gragh[v2];
    }
    int doneV = 0;
    int result[nodeNum]; // 存放结果
    while(doneV != nodeNum){
        int stillUpdate = 0; // 标志是否可以退出循环(如果遍历了一遍以后没有要输出的节点,那么停止)
        for(int i = 0; i < nodeNum; i ++){
            if(cover[i] == 1){
                continue;
            }
            if(gragh[i]->inNum == 0){
                result[doneV ++] = i + 1;
                stillUpdate = 1;
                cover[i] = 1;
                // printf("delete %d cover:%d, doneV:%d, outNum %d\n", i+1, cover[i], doneV, gragh[i]->outNum);
                for(int j = 0;j < gragh[i]->outNum; j ++){
                    gragh[i]->adj[j]->inNum --;
                }
                // 记得释放内存
                free(gragh[i]);
                gragh[i] = NULL;
            }
        }
        if(!stillUpdate){
            break;
        }
    }
    if(doneV == nodeNum){
        for(int i = 0; i < nodeNum-1; i ++){
            printf("%d ", result[i]);
        }
        printf("%d", result[nodeNum - 1]);
    }else{
        printf("-1");
    }
    return 0;
}

三、总结

很久没有做和图相关的题了,有点生疏,这里用一个数组存放图中的每一个节点,每个节点的邻接点也用数组存放,同时记录每个节点的入度出度和编号。
首先是一个大循环,在大循环里,循环遍历每一个点,输出入度为0的点,如果一个大循环下来,没有要输出的点,那么退出大循环。

目录
相关文章
|
2天前
|
人工智能 算法 测试技术
【数学】【排序】【C++算法】3027人员站位的方案数
【数学】【排序】【C++算法】3027人员站位的方案数
|
2天前
|
人工智能 算法 BI
【优选算法专栏】专题十八:BFS解决拓扑排序(一)
【优选算法专栏】专题十八:BFS解决拓扑排序(一)
20 0
|
2天前
|
算法
【优选算法专栏】专题十八:BFS解决拓扑排序--前言
【优选算法专栏】专题十八:BFS解决拓扑排序--前言
22 1
|
2天前
|
算法
常见的算法排序(2)
常见的算法排序(2)
12 3
|
2天前
|
算法 搜索推荐 索引
数据结构与算法 排序(下)
数据结构与算法 排序(下)
12 1
|
2天前
|
缓存 算法 搜索推荐
数据结构与算法 排序(上)
数据结构与算法 排序(上)
11 0
|
2天前
|
算法 调度
【问题探讨】基于非支配排序的蜣螂优化算法NSDBO求解微电网多目标优化调度研究
【问题探讨】基于非支配排序的蜣螂优化算法NSDBO求解微电网多目标优化调度研究
|
2天前
|
搜索推荐 C语言
【C语言/数据结构】排序(归并排序|计数排序|排序算法复杂度)
【C语言/数据结构】排序(归并排序|计数排序|排序算法复杂度)
11 0
|
2天前
|
算法
讲课:拓扑排序、最短路算法
讲课:拓扑排序、最短路算法
|
2天前
|
算法 测试技术 C#
【模拟】【C++算法】2826. 将三个组排序
【模拟】【C++算法】2826. 将三个组排序