首页 > 其他分享 >代码随想录训练营第63天|拓扑排序

代码随想录训练营第63天|拓扑排序

时间:2024-10-15 13:49:52浏览次数:3  
标签:vector int inDegree 训练营 入度 随想录 63 include 节点

117. 软件构建

#include <iostream>
#include <vector>
#include <queue>
#include <unordered_map>
using namespace std;
int main() {
    int m, n, s, t;
    cin >> n >> m;
    vector<int> inDegree(n, 0); // 记录每个文件的入度

    unordered_map<int, vector<int>> umap;// 记录文件依赖关系
    vector<int> result; // 记录结果

    while (m--) {
        // s->t,先有s才能有t
        cin >> s >> t;
        inDegree[t]++; // t的入度加一
        umap[s].push_back(t); // 记录s指向哪些文件
    }
    queue<int> que;
    for (int i = 0; i < n; i++) {
        // 入度为0的文件,可以作为开头,先加入队列
        if (inDegree[i] == 0) 
            que.push(i);
        //cout << inDegree[i] << endl;
    }

    while (!que.empty()) {
        int  cur = que.front(); // 当前选中的文件
        que.pop();
        result.push_back(cur);
        vector<int> files = umap[cur]; //获取该文件指向的文件

        for (auto file:files) {
            inDegree[file]--; // cur的指向的文件入度-1
            if(inDegree[file] == 0) 
                que.push(file);
        }
        
    }
    if (result.size() == n) {
        for (int i = 0; i < n - 1; i++) 
            cout << result[i] << " ";
        cout << result[n - 1];
    } 
    else
        cout << -1 << endl;
}

拓扑排序问题:不断加入入度为0的点,每次加入新的节点后,对剩余的节点更新入度。

47. 参加科学大会

#include <iostream>
#include <vector>
#include <climits>
using namespace std;
int main() {
    int n, m, p1, p2, val;
    cin >> n >> m;

    vector<vector<int>> grid(n + 1, vector<int>(n + 1, INT_MAX));
    for(int i = 0; i < m; i++){
        cin >> p1 >> p2 >> val;
        grid[p1][p2] = val;
    }

    int start = 1;
    int end = n;

    // 存储从源点到每个节点的最短距离
    std::vector<int> minDist(n + 1, INT_MAX);

    // 记录顶点是否被访问过
    std::vector<bool> visited(n + 1, false);

    minDist[start] = 0;  // 起始点到自身的距离为0

    for (int i = 1; i <= n; i++) { // 遍历所有节点

        int minVal = INT_MAX;
        int cur = 1;

        // 1、选距离源点最近且未访问过的节点
        for (int v = 1; v <= n; ++v) {
            if (!visited[v] && minDist[v] < minVal) {
                minVal = minDist[v];
                cur = v;
            }
        }

        visited[cur] = true;  // 2、标记该节点已被访问

        // 3、第三步,更新非访问节点到源点的距离(即更新minDist数组)
        for (int v = 1; v <= n; v++) {
            if (!visited[v] && grid[cur][v] != INT_MAX && minDist[cur] + grid[cur][v] < minDist[v]) {
                minDist[v] = minDist[cur] + grid[cur][v];
            }
        }

    }

    if (minDist[end] == INT_MAX) 
        cout << -1 << endl; // 不能到达终点
    else 
        cout << minDist[end] << endl; // 到达终点最短路径

}

dijkstra三部曲:

  1. 第一步,选源点到哪个节点近且该节点未被访问过
  2. 第二步,该最近节点被标记访问过
  3. 第三步,更新非访问节点到源点的距离(即更新minDist数组)

标签:vector,int,inDegree,训练营,入度,随想录,63,include,节点
From: https://blog.csdn.net/jiyisuifeng1991/article/details/142940731

相关文章

  • 代码随想录训练营第62天|最小生成树
    53.寻宝#include<iostream>#include<vector>#include<climits>usingnamespacestd;intmain(){intv,e;intx,y,k;cin>>v>>e;//填一个默认最大值,题目描述val最大为10000vector<vector<int>>grid(v+1......
  • 代码随想录算法训练营day15| 110.平衡二叉树 257.二叉树的所有路径 404.左叶子之和
    学习资料:https://programmercarl.com/0110.平衡二叉树.html#算法公开课平衡二叉树:任意一个节点的左右子树高度差不超过1左叶子:是叶子节点,且是其父节点的左节点完全二叉树:上层均满,底层的节点从左到右连续满二叉树:每层都是满的,节点总数为(2^k+1)语法:2<<1是2^2学习记录:1......
  • 牛客周赛63部分题解
    比赛地址:牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ(nowcoder.com)A.小红的好数#include<bits/stdc++.h>usingnamespacestd;#definelllonglong#defineullunsignedlonglongvoidsolve(){lln;cin>>n;if(n>=10&&n<=99......
  • 代码随想录算法训练营 | 121.买卖股票的最佳时机,122.买卖股票的最佳时机II,123.买卖股
    121.买卖股票的最佳时机题目链接:121.买卖股票的最佳时机文档讲解︰代码随想录(programmercarl.com)视频讲解︰买卖股票的最佳时机日期:2024-10-14想法:经常有用0和1表示相反状态,dp[i][0]表示第i天持有股票时身上最多的钱,比如第一天股票5元,持有了,身上的钱就为dp[0][0]=-5,第二天股......
  • 洛谷P1638逛画展
    逛画展题目链接题目描述博览馆正在展出由世上最佳的\(m\)位画家所画的图画。游客在购买门票时必须说明两个数字,\(a\)和\(b\),代表他要看展览中的第\(a\)幅至第\(b\)幅画(包含\(a,b\))之间的所有图画,而门票的价钱就是一张图画一元。Sept希望入场后可以看到所有名师的图......
  • 2024牛客暑期多校训练营4 - J. Zero (究极卡常)
    \(O(N^2)\)AC。输入后预处理?数量的前缀和。双层循环找所有的区间\([l,r]\)使区间内没有\(0\),找到以后直接用逆元+快速幂求\(\frac{(r-l+1)^k}{2^{sum_{r}-sum_{l-1}}}\),最后累加和。因为数据过水,这样已经能AC了。#include<cstdio>usingnamespacestd;constint......
  • 代码随想录算法训练营第三十四天|134. 加油站 135. 分发糖果 860.柠檬水找零 406.根据
    134.加油站在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升。你有一辆油箱容量无限的的汽车,从第i个加油站开往第i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。如果你可以绕环路行驶一周,则返回出发时加油站的......
  • 代码随想录算法训练营第三十二天|122.买卖股票的最佳时机 II 55. 跳跃游戏 45.跳跃游
    122.买卖股票的最佳时机II给定一个数组,它的第 i个元素是一支给定股票第i天的价格。设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。示例1:输入:[7,1,5......
  • 代码随想录算法训练营第三十一天|455.分发饼干 376. 摆动序列 53. 最大子序和
    455.分发饼干假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。对每个孩子i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干j,都有一个尺寸s[j] 。如果s[j] >=g[i],我们可以将这个饼干j分配给孩子i,......
  • 代码随想录算法训练营第八天(1)|哈希表理论基础
    文档讲解:代码随想录难度:有一点哈希表理论基础哈希表首先什么是哈希表,哈希表(英文名字为Hashtable,国内也有一些算法书籍翻译为散列表,大家看到这两个名称知道都是指hashtable就可以了)。哈希表是根据关键码的值而直接进行访问的数据结构。这么官方的解释可能有点懵,其实......