首页 > 其他分享 >Pintia 天梯地图 dijkstra进阶

Pintia 天梯地图 dijkstra进阶

时间:2024-03-31 12:55:40浏览次数:21  
标签:node ok 进阶 int cout Pintia dijkstra dis

7-14 天梯地图 - SMU 2024 spring 天梯赛3(补题) (pintia.cn)

dijkstra进阶做法,包含路径记录,以及按权重统计路径条件等;

不过最开始我一直将优先队列开的最大堆,但是一直过不了自己的例子,后来改成最小堆并且路径值改成负数存进去就对了,再后来我发现改成最大堆也可以,不过要把点值改成负数,最后才焕然大悟,这题路径取最短的同时,节点值也应该尽量的小(

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;

struct DIJ {
    using i64 = long long;
    using PII = pair<i64, i64>;
    vector<i64> dis, path, node;
    vector<vector<array<int, 3>>> G;
    int n;

    DIJ() {}
    DIJ(int n): n(n) {
        node.resize(n + 1, 1);
        dis.assign(n + 1, 1e18);
        G.resize(n + 1);
        path.resize(n + 1, -1);
    }

    void add(int u, int v, int w, int val) {
        G[u].push_back({v, w, val});
    }

    void dijkstra(int s) {
        priority_queue<PII,vector<PII>,greater<PII>> que;
        dis[s] = 0;
        que.push({0, -s});
        while (!que.empty()) {
            auto p = que.top();
            que.pop();
            int u = -p.second;
            if (dis[u] < p.first) continue;
            for (auto [v, w, val] : G[u]) {
                if (dis[v] > dis[u] + w) {
                    node[v] = node[u] + val;
                    dis[v] = dis[u] + w;
                    que.push({ dis[v], -v});
                    path[v] = u;
                } else if (dis[v] == dis[u] + w) {
                    if (node[v] > node[u] + val) {
                        node[v] = node[u] + val;
                        path[v] = u;
                    }
                }
            }
        }
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m;
    cin >> n >> m;
    DIJ time(n), way(n);
    while (m --) {
        int u, v, c, t, w;
        cin >> u >> v >> c >> w >> t;
        time.add(u, v, t, w);
        way.add(u, v, w, 1);
        if (!c) {
            time.add(v, u, t, w);
            way.add(v, u, w, 1);
        }
    }

    int st, ed, ok;
    cin >> st >> ed;
    time.dijkstra(st);
    way.dijkstra(st);

    ok = ed;
    vector<int> ans, ans1;
    while (ok != -1) {
        ans.push_back(ok);
        ok = time.path[ok];
    }
    ok = ed;
    while (ok != -1) {
        ans1.push_back(ok);
        ok = way.path[ok];
    }

    if (ans1 == ans) {
        cout << "Time = " << time.dis[ed] << "; ";
        cout << "Distance = " << way.dis[ed] << ": ";
        for (int i = ans1.size() - 1; i >= 0; i --) {
            cout << ans1[i] ;
            if (i) cout << " => ";
            else cout << '\n';
        }
    } else {
        cout << "Time = " << time.dis[ed] << ": ";
        for (int i = ans.size() - 1; i >= 0; i --) {
            cout << ans[i] ;
            if (i) cout << " => ";
            else cout << '\n';
        }
        cout << "Distance = " << way.dis[ed] << ": ";
        for (int i = ans1.size() - 1; i >= 0; i --) {
            cout << ans1[i] ;
            if (i) cout << " => ";
            else cout << '\n';
        }
    }

    return 0;
}

标签:node,ok,进阶,int,cout,Pintia,dijkstra,dis
From: https://www.cnblogs.com/Kescholar/p/18106611

相关文章

  • Python之Opencv进阶教程(2):统计图片灰度级别的像素数量
    1、什么是灰度像素数量在OpenCV中,可以使用**cv2.calcHist()**函数来计算图像的直方图。直方图是一种图形统计表,用于表示图像中每个灰度级别(或颜色通道)的像素数量或密度分布。以下是一个示例代码,演示了如何使用OpenCV计算和绘制图像的直方图:2、代码importcv2ascvimpor......
  • Python之Opencv进阶教程(1):图片模糊
    1、Opencv提供了多种模糊图片的方法加载原始未经模糊处理的图片importcv2ascvimg=cv.imread('../Resources/Photos/girl.jpg')cv.imshow('girl',img)1.1平均值关键代码#Averaging平均值a......
  • RSA进阶(一)
    本篇为RSA进阶篇,继RSA入门[RSA3]P1(扩展欧几里得)题目fromCrypto.Util.numberimport*flag=b'******'m1=bytes_to_long(flag[:len(flag)//2])m2=bytes_to_long(flag[len(flag)//2:])assert18608629446895353521310408885845687520013234781800558*m1-142588104721......
  • 4、Pico Robot 传感器进阶课程
    4.1光敏传感器一、学习目标1.学习树莓派Pico主板和小车扩展板的光敏传感器、OLED结合进行实验。2.了解光敏传感器的使用。二、硬件使用本次课程使用PICO主板以及小车扩展板的光敏传感器、OLED,运行之前请把跳线帽接到Light排针。光敏电阻是用硫化镉或硒化镉等半导体材料......
  • AI绘图:Stable Diffusion WEB UI 详细操作介绍:进阶-面部修复和调参
    结合两篇文章完成了本地部署和基础操作,现在我们来介绍下进阶内容:面部修复,高清修复和调参区。一:脸部修复面部修复的适用在画真人、三次元的场景,特别是在画全身的时候一般在画全身,由于脸部占比的空间比较小,那么绘制出来的效果就会比较差1.面部修复SD支持直接一键进行脸部修......
  • 算法进阶课之搜索
    在y总的算法进阶课里,主要讲了BFS和DFS虽然y总将二者又细分成了很多类别(bfs下面有floodfill、最短路模型、最小步数模型……)但个人感觉bfs没有必要分这么多种以下是一些总结:1、bfsvsdfs:前者可以用来求最短(保证第一次搜到的是最短的)但是需要用很多的空间,而且代码相对复杂一些;......
  • 第十一章 :Linux 进阶finalshell操作
    指令不会可以后面加--help 例如find--help1)数据输出echo格式 echo数据 将数据输出展示到终端界面列入 echo helloworld 将会输出 helloworldecho pwd 将会只输出pwd(pwd当作文字输出)则echo·pwd·(ESC下面的反引号)输出的是当前目录 ......
  • Linux进阶命令
    Linux进阶命令①1查看切换显示统计目录1.pwd(printworkdirectory)[root@localhost~]#pwd//显示当前路径/root[root@localhostbin]#cd/bin[root@localhostbin]#ll/binlrwxrwxrwx.1rootroot78月620:57/bin->usr/bin[root@localhostbin]#pwd-......
  • Mybatis进阶之动态SQL
    1、MyBatis获取参数值的两种方式MyBatis获取参数值的两种方式:${}和#{}${}的本质就是字符串拼接,#{}的本质就是占位符赋值${}使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引号;但是#{}使用占位符赋值的方式拼接sql,此时为字符串类型或日......
  • 泛型的进阶
    1通配符?我们想调用fun函数帮我们打印,但由于不知道Message具体是什么类型,所以我们可以使用:?即通配符当我们将fun函数中改为Message<?>此时就不会报错2通配符的上界:<?extends上界>Demo:<?extendsFruit>意思是传入的实参需要是Fruit或者Fruit的子类当我们用通配......