代码随想录算法训练营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;
}

相关推荐
show43318 小时前
2026小程序端AI智能优化技术实践:转文字后自动纠错+润色+分段算法分析
人工智能·算法·小程序
郝学胜_神的一滴18 小时前
C++20 高级编程 003:吃透现代基础语法与标准容器
c++
码匠许师傅18 小时前
【C++ 面试真题】聊聊 C++ 的关联容器
开发语言·c++·面试
平生不晚19 小时前
在 SVG 体系里画一条任意的线
前端·算法
Hhy_110719 小时前
《C++深度解构02》类和对象(上)——定义规范、内存对齐与 this 指针全解
c语言·开发语言·c++·学习·visual studio
晚风叙码19 小时前
C++哈希表实现:开放定址法和链地址法 (哈希桶)
数据结构·c++·哈希算法·散列表
逆境不可逃20 小时前
LeetCode 双题:415. 字符串相加与 143. 重排链表
算法
2601_9507607920 小时前
TNF-α:自身免疫疾病治疗的核心靶点与信号通路解析
人工智能·算法·蛋白
呜喵王阿尔萨斯20 小时前
C/C++ 杂记-1
c++
不会代码的小猴20 小时前
2. 了解Qt
开发语言·c++·笔记·qt·算法