代码随想录算法训练营Day-58 图论08 | 拓扑排序精讲、dijkstra(朴素版)精讲

拓扑排序精讲

一堆软件有前置依赖关系,找到一条可行的安装顺序

思路:

1.找到入度为0的节点;2.将入度为0的节点加入结果集,然后删除该节点。重复以上过程即可

细节:

入度用一个数组记录,记录每个节点的入度;

**如何删除节点?**只需把节点所连接的子节点的入度都减一;

如何找到节点所连接的所有子节点? 定义一个键值对,键是父节点,值是所连接的节点组成的数组;

**如何找到入度为0的节点?**不需要每次都遍历,只需要在遇到入度为0的节点时就加入队列,然后只要队列不空,就循环执行"将队头取出,加入结果集,删除队头,删除节点,再判断节点连接的子节点是否入度为0,如果是就也加入"。

cpp 复制代码
#include<iostream>
using namespace std;
#include<vector>
#include<queue>
#include<unordered_map>

int main(){
    int n,m,s,t;
    cin>>n>>m;
    vector<int> indegree(n,0);
    vector<int> result;
    unordered_map<int,vector<int>> umap;
    queue<int> que;

    while(m--){
        cin>>s>>t;
        indegree[t]++;
        umap[s].push_back(t);
    }

    for(int i=0;i<n;i++){
        if(indegree[i]==0){
            que.push(i);
        }
    }

    while(!que.empty()){
        int cur = que.front(); que.pop();
        result.push_back(cur);
        vector<int> notes = umap[cur];
        if(notes.size()){
            for(int i=0;i<notes.size();i++){
                indegree[notes[i]]--;
                if(indegree[notes[i]]==0) que.push(notes[i]);
            }
        } 
    }
    if(n == result.size()){
        for(int i=0;i<n-1;i++){
            cout<<result[i]<<" ";
        }
        cout<<result[n-1]<<endl;
    }else{
        cout<<-1<<endl;
    }

}

dijkstra(朴素版)精讲

本题是在有向有权图中,找到起点到终点的最短路径距离

思路:和prim算法高度类似

1.找到距离起点最近的没被访问过的节点(搜索minDist中的没被访问过的节点的最小值)

2.将该节点标记为访问过(将visitedcur置为true)

3.更新所有没被访问过的节点到起点的最短距离(遍历节点,判断节点是否访问过 && 是否和当前节点连接 && 是否到起点的距离小于之前记录的距离(因为如果途径新的当前节点可能会获得更短的距离))

cpp 复制代码
#include<iostream>
#include<vector>
#include <climits>
using namespace std;
int main(){
    int n,m,s,t,val;
    cin>>n>>m;
    vector<vector<int>> graph(n+1,vector<int>(n+1,INT_MAX));
    while(m--){
        cin>>s>>t>>val;
        graph[s][t]= val;
    }

    vector<int> minDist(n+1, INT_MAX);
    vector<bool> visited(n+1, false);
    int start = 1; 
    int end = n;
    minDist[1] = 0;
    for(int i=1;i<=n;i++){
        int cur = 1;
        int minval = INT_MAX;
        for(int j=1;j<=n;j++){
            if(visited[j]==false && minval>minDist[j]){
                minval = minDist[j];
                cur = j;
            }
        }

        visited[cur] = true;
        for(int k=1;k<=n;k++){
            if(visited[k] == false &&graph[cur][k]!=INT_MAX && graph[cur][k]+minDist[cur]<minDist[k]){
                minDist[k] = graph[cur][k]+minDist[cur];
            }
        }
    }
    if(minDist[n]==INT_MAX){
        cout<<-1<<endl;
        return 0;
    }
    cout<<minDist[n]<<endl;
}

相关推荐
吃好睡好便好7 小时前
矩阵的乘法运算
数据结构·人工智能·学习·线性代数·算法·matlab·矩阵
Ricky05538 小时前
RF-DETR:实时检测变换器(transformers)的神经架构搜索(美国2025.12研究)
图像处理·人工智能·算法
丘山望岳8 小时前
藤萝垂序——二叉搜索树
开发语言·数据结构·c++
Qhappy8 小时前
某里v2反混淆 codec 化路上踩到的两个隐蔽坑:被清零的 salt 与 opaque loop bound
javascript·算法
Hello world.Joey8 小时前
吴恩达深度学习基础
人工智能·深度学习·神经网络·opencv·算法·机器学习·计算机视觉
水木流年追梦8 小时前
大模型入门-大模型优化方法1
人工智能·学习·算法·机器学习·正则表达式
光电笑映8 小时前
深入理解 ELF:从目标文件到程序加载的全过程
linux·运维·服务器·c++
lynnlovemin9 小时前
【信息学竞赛专题】滑动窗口(尺取法)超全详解|C++模板+经典例题+避坑指南
开发语言·c++·算法·滑动窗口·信息学竞赛
不会C语言的男孩9 小时前
VS Code 中搭建 C/C++ 开发环境(MSYS2 编译器)
c语言·c++