acwing算法提高之图论--单源最短路的建图方式

目录

  • [1 介绍](#1 介绍)
  • [2 训练](#2 训练)

1 介绍

本博客用来记录使用dijkstra算法或spfa算法求解最短路问题的题目。

2 训练

题目11129热浪

C++代码如下,

cpp 复制代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

const int N = 2510;
int n, m;
vector<vector<pair<int,int>>> g; //first表示next_node,second表示w
int dist[N];
bool st[N];
int snode, enode;

void dijkstra() {
    memset(dist, 0x3f, sizeof dist);
    dist[snode] = 0;
    
    priority_queue<pair<int, int>, vector<pair<int,int>>, greater<pair<int,int>>> h;
    h.push(make_pair(0, snode));
    
    while (!h.empty()) {
        //确定当前结点中,不在集合s且距离结点snode最近的结点。记作cnode
        auto t = h.top();
        h.pop();
        int cdist = t.first, cnode = t.second;
        if (st[cnode]) continue; //如果cnode已经被确定是最小路径上的结点了,则跳过
        
        st[cnode] = true; //将它加入到集合中
        for (auto [next_node, w] : g[cnode]) {
            if (dist[next_node] > cdist + w) {
                dist[next_node] = cdist + w;
                h.push(make_pair(dist[next_node], next_node));
            }
        }
    }
    
    return;
}

int main() {
    cin >> n >> m >> snode >> enode;
    g.resize(n + 10);
    
    for (int i = 1; i <= m; ++i) {
        int a, b, c;
        cin >> a >> b >> c;
        g[a].emplace_back(b, c);
        g[b].emplace_back(a, c);
    }
    
    //求snode到enode的最短距离
    dijkstra();
    
    cout << dist[enode] << endl;
    
    return 0;
}

题目21128信使

C++代码如下,

cpp 复制代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

const int N = 110;
int n, m;
int d[N];
bool st[N];
vector<vector<pair<int,int>>> g;

void dijkstra() {
    memset(d, 0x3f, sizeof d);
    
    d[1] = 0;
    
    priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> hp; //小根堆
    hp.push(make_pair(0, 1)); //first表示距离,second表示结点
    
    while (!hp.empty()) {
        
        auto t = hp.top(); //找到未在集合中,距离最小的结点
        hp.pop();
        
        int a = t.second;
        
        if (st[a]) continue; //已经用d[a]更新过了,将它放入集合中
        
        st[a] = true;
        for (auto [b, w] : g[a]) {
            if (d[b] > d[a] +w) { //d[b]此时比较大,用一个更小值来更新它。
                d[b] = d[a] + w;
                hp.push(make_pair(d[b], b));
            }
        }
    }
    
    return;
}

int main() {
    cin >> n >> m;
    g.resize(n + 10);
    for (int i = 0; i < m; ++i) {
        int a, b, c;
        cin >> a >> b >> c;
        g[a].emplace_back(b, c);
        g[b].emplace_back(a, c);
    }
    
    dijkstra();
    
    int res = 0; //求最大值
    for (int i = 1; i <= n; ++i) res = max(res, d[i]);
    if (res == 0x3f3f3f3f) {
        res = -1;
    }
    cout << res << endl;
    
    return 0;
}

题目31127香甜的黄油

C++代码如下,

cpp 复制代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <climits>
#include <vector>
#include <queue>

using namespace std;

const int N = 810;
int cow, n, m;
int cnt[N];
int d[N];
bool st[N];
vector<vector<pair<int,int>>> g;

void spfa(int start) {
    //起点为start
    
    memset(d, 0x3f, sizeof d);
    memset(st, 0, sizeof st);
    
    d[start] = 0;
    
    queue<int> q;
    q.push(start);
    st[start] = true; //结点start在队列中
    
    while (!q.empty()) {
        int t = q.front();
        q.pop();
        st[t] = false; //结点t不在队列中了
        
        for (auto [b, w] : g[t]) {
            if (d[b] > d[t] + w) {
                d[b] = d[t] + w;
                if (!st[b]) {
                    q.push(b);
                    st[b] = true;
                }
            }
        }
    }
    
    return;
}

int main() {
    cin >> cow >> n >> m;
    g.resize(n + 10);
    for (int i = 1; i <= cow; ++i) {
        int a;
        cin >> a; //每头牛所在的牧场
        cnt[a]++;
    }
    
    for (int i = 1; i <= m; ++i) {
        int a, b, c;
        cin >> a >> b >> c;
        g[a].emplace_back(b, c);
        g[b].emplace_back(a, c);
    }
    
    
    //spfa()算法 //o(m)时间复杂度,不会被超时
    long long res = INT_MAX;
    for (int i = 1; i <= n; ++i) {
        //第i个牧场作为放糖点
        
        spfa(i);
        long long t = 0; 
        for (int j = 1; j <= n; ++j) t += cnt[j] * d[j];
        res = min(res, t);
    }
    
    cout << res << endl;
    
    return 0;
}

题目41126最小花费

cpp 复制代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>

using namespace std;

const int N = 2010;
int n, m;
int snode, enode;
double d[N]; //求最大距离,最大利率
bool st[N]; //是否使用它来更新过
vector<vector<pair<int,int>>> g;

void dijkstra() {
    //d的初始化
    for (int i = 1; i <= n; ++i) d[i] = 0.0; //初始成0.0
    
    memset(st, 0, sizeof st);
    
    d[snode] = 1.0;
    
    priority_queue<pair<double,int>> hp; //大根堆
    hp.push(make_pair(1.0, snode));
    
    while (!hp.empty()) {
        auto t = hp.top();
        hp.pop();
        
        int a = t.second;
        
        if (st[a]) continue;
        
        st[a] = true;
        for (auto [b, w] : g[a]) {
            if (d[b] < d[a] * 0.01 * (100 - w)) {
                d[b] = d[a] * 0.01 * (100 - w);
                hp.push(make_pair(d[b], b));
            }
        }
    }
    
    return;
}

int main() {
    cin >> n >> m;
    g.resize(n + 10);
    
    for (int i = 1; i <= m; ++i) {
        int a, b, c;
        cin >> a >> b >> c;
        g[a].emplace_back(b, c);
        g[b].emplace_back(a, c);
    }
    
    cin >> snode >> enode;
    
    dijkstra();
    
    double res = 100.0 / d[enode];
    printf("%.8f\n", res);
    
    return 0;
}

题目5

相关推荐
江畔柳前堤6 小时前
大语言模型分布式训练:从并行策略到万卡工程的系统梳理
人工智能·分布式·深度学习·算法·目标检测·机器学习·语言模型
Forever Nore7 小时前
LeetCode 4 寻找两个正序数组的中位数 - 二分
算法·leetcode
罗西的思考9 小时前
【OpenClaw具身硬件】MiniClaw 阅读笔记---(1)基础
人工智能·算法·机器学习
蛋先生DX9 小时前
大模型参数存储格式揭秘:BF不是男朋友
深度学习·算法·llm
爱跳舞的烤冷面10 小时前
自学嵌入式第22天(数据结构——哈希)
数据结构·算法·哈希算法
猎嘤一号10 小时前
博弈论(Game Theory)的理论、算法与工程
人工智能·算法·安全·博弈论
月光船幽幽10 小时前
影子模式下保护 logits 不被修改
人工智能·python·算法
马拉AI11 小时前
腾讯开源 Agent 记忆系统,AI“换对话就忘”的问题有了新解法(附安装使用教程)
人工智能·算法·开源·科研
地平线开发者12 小时前
征程6工具链模型X86推理方式说明
算法
地平线开发者12 小时前
【征程6】校准量化中HistogramObserver解析
算法