第二十四天打卡 拓扑排序(有向拓扑序列)

于颜 于颜 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区

 思路

代码 

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010;
int e[N], ne[N], idx;//邻接表存储图
int h[N];
int q[N], hh = 0, tt = -1;//队列保存入度为0的点,也就是能够输出的点,
int n, m;//保存图的点数和边数
int d[N];////保存各个点的入度

void add(int a, int b){
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

void topsort(){
    for(int i = 1; i <= n; i++){//遍历一遍顶点的入度。
        if(d[i] == 0)//如果入度为 0, 则可以入队列
            q[++tt] = i;
    }
    while(tt >= hh){//循环处理队列中点的
        int a = q[hh++];
        for(int i = h[a]; i != -1; i = ne[i]){//循环删除 a 发出的边
            int b = e[i];//a 有一条边指向b
            d[b]--;//删除边后,b的入度减1
            if(d[b] == 0)//如果b的入度减为 0,则 b 可以输出,入队列
                q[++tt] = b;
        }
    }
    if(tt == n - 1){//如果队列中的点的个数与图中点的个数相同,则可以进行拓扑排序
        for(int i = 0; i < n; i++){//队列中保存了所有入度为0的点,依次输出
            cout << q[i] << " ";
        }
    }
    else//如果队列中的点的个数与图中点的个数不相同,则可以进行拓扑排序
        cout << -1;//输出-1,代表错误
}


int main(){
    cin >> n >> m;//保存点的个数和边的个数
    memset(h, -1, sizeof h);//初始化邻接矩阵
    while (m -- ){//依次读入边
        int a, b;
        cin >> a >> b;
        d[b]++;//顶点b的入度+1
        add(a, b);//添加到邻接矩阵
    }
    topsort();//进行拓扑排序
    return 0;
}

python

N = 100010
e = [0]*N
ne = [0]*N
h = [-1]*N
idx = 0
# 入队
q = [0]*N
# 入度
d = [0]*N

def add(a,b):
    global idx
    e[idx] = b
    ne[idx] = h[a]
    h[a] = idx
    idx += 1

def topsort():
    hh,tt = 0, -1
    # 由于入度的点是从1 ~ n,因此是从1 ~ n 遍历,如果有入度为0的点,则把它入队
    for i in range(1,n+1):
        if not d[i]:
            tt += 1
            q[tt] = i

    while hh <= tt:
        t = q[hh]
        hh += 1
        i = h[t]
        while i != -1:
            j = e[i]
            # 入度减一
            d[j] -= 1
            if d[j] == 0:
                tt += 1
                q[tt] = j
            i = ne[i]

    return tt == n - 1

n,m = map(int,input().split())

while m:
    m -= 1
    a,b = map(int,input().split())
    # 添加从a -> b 的一条边,b的入度 + 1
    add(a,b)
    d[b] += 1 

if topsort():
    for i in range(n):
        print(q[i],end=" ")
else:
    print(-1)

 

...全文

相关推荐

一款不用手动打卡,自动调起钉钉上班打卡的App

该项目是一款自动化安卓应用,旨在实现无需手动操作即可自动启动钉钉进行上班打卡。通过集成Android架构组件与生命周期管理库,结合Gradle构建系统完成项目配置和依赖管理,利用系统级服务或定时任务触

徐玮大人

系统集成项目管理工程师打卡第二十四天.doc

"系统集成项目管理工程师第二十四天学习内容涉及项目启动阶段的问题分析"案例中的项目启动过程中暴露出一系列问题,这些问题对于项目的顺利进行构成了潜在的风险和挑战。以下是问题的具体分析:1) *

weixin_54171196

安卓 钉钉定位打卡,安卓 钉钉定位打卡,安卓 钉钉定位打卡

同时,为了避免虚假打卡,钉钉通常会对连续的定位信息进行比对,确保打卡地点与预设的工作地点相符。3. **打卡规则设定** 管理员可以在钉钉后台设置详细的打卡规则,包括上下班时间、打卡范围等。

qq_17550513

2021最新手账系列-记忆曲线打卡表(30天).pdf

根据提供的文件信息,我们可以推断出文件《2021最新手账系列-记忆曲线打卡表(30天).pdf》中包含了关于艾宾浩斯遗忘曲线以及其在学习中的应用——30天复习计划的知识点。

xiaomaodiaoyu520

2021最新手账系列-记忆曲线打卡表(100天).pdf

在本文件中,艾宾浩斯遗忘曲线被用作100天记忆打卡表的设计原理,这是一套高效的记忆管理工具,结合了时间管理和复习策略。接下来,详细解释这些知识点:首先,艾宾浩斯遗忘曲线描述的是记忆随时间递减的情况。

xiaomaodiaoyu520
评论
收藏 已收藏
分享
返回顶部