题解 | 【模板】拓扑排序

【模板】拓扑排序

https://www.nowcoder.com/practice/88f7e156ca7d43a1a535f619cd3f495c

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

#define MAXN 200000

// 定义边的结构体
typedef struct Edge {
    int to;
    struct Edge* next;
} Edge;

// 定义邻接表表头数组
Edge* adj[MAXN];
// 入度数组
int inDegree[MAXN];
// 拓扑排序结果数组
int topoOrder[MAXN];
// 队列数组
int queue[MAXN];

// 添加边到邻接表
void addEdge(int u, int v) {
    Edge* newEdge = (Edge*)malloc(sizeof(Edge));
    newEdge->to = v;
    newEdge->next = adj[u];
    adj[u] = newEdge;
    inDegree[v]++;
}

// 拓扑排序函数
int topologicalSort(int n) {
    int front = 0, rear = 0;
    // 将入度为 0 的节点入队
    for (int i = 1; i <= n; i++) {
        if (inDegree[i] == 0) {
            queue[rear] = i;
            rear++;
        }
    }
    int index = 0;
    while (front < rear) {
        int u = queue[front];
        front++;
        topoOrder[index] = u;
        index++;
        Edge* p = adj[u];
        while (p != NULL) {
            int v = p->to;
            inDegree[v]--;
            if (inDegree[v] == 0) {
                queue[rear] = v;
                rear++;
            }
            p = p->next;
        }
    }
    // 如果拓扑排序结果节点数不等于总节点数,说明图中有环
    return index == n;
}

int main() {
    int n, m;
    scanf("%d %d", &n, &m);
    // 初始化邻接表和入度数组
    for (int i = 1; i <= n; i++) {
        adj[i] = NULL;
        inDegree[i] = 0;
    }
    // 读入边信息并添加到邻接表
    for (int i = 0; i < m; i++) {
        int u, v;
        scanf("%d %d", &u, &v);
        addEdge(u, v);
    }
    // 进行拓扑排序
    if (topologicalSort(n)) {
        for (int i = 0; i < n; i++) {
            if (i > 0) {
                printf(" ");
            }
            printf("%d", topoOrder[i]);
        }
        printf("\n");
    } else {
        printf("-1\n");
    }
    // 释放邻接表内存
    for (int i = 1; i <= n; i++) {
        Edge* p = adj[i];
        while (p != NULL) {
            Edge* temp = p;
            p = p->next;
            free(temp);
        }
    }
    return 0;
}

全部评论

相关推荐

点赞 评论 收藏
分享
05-07 17:58
门头沟学院 Java
wuwuwuoow:1.简历字体有些怪怪的,用啥写的? 2.Redis 一主二从为什么能解决双写一致性? 3.乐观锁指的是 SQL 层面的库存判断?比如 stock > 0。个人认为这种不算乐观锁,更像是乐观锁的思想,写 SQL 避免不了悲观锁的 4.奖项证书如果不是 ACM,说实话没什么必要写 5.逻辑过期时间为什么能解决缓存击穿问题?逻辑过期指的是什么 其实也没什么多大要改的。海投吧
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务