算法——图论——最短路径(多边权)

原题

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

using namespace std;
typedef pair<int, int> PII;

vector<int> cityIndex(100, 0);
vector<PII> graph[100];
vector<int> Dist(100, -1);
vector<bool> State(100, false);
vector<int> lastNode[100];

struct pqNode {
    int destination;
    int dist;
    int lastNode;

    pqNode(int destination_, int dist_, int lastNode_) : destination(destination_), dist(dist_), lastNode(lastNode_) {}
};

struct compare {
    bool operator()(pqNode lhs, pqNode rhs) {
        return lhs.dist > rhs.dist;
    }
};

vector<vector<int>> Paths;
vector<int> tmpPath;

void dfs(int s, int t) {
    if (s == t) {
        tmpPath.push_back(s);
        Paths.push_back(tmpPath);
        tmpPath.pop_back();
        return;
    }
    for (int last: lastNode[t]) {
        tmpPath.push_back(t);
        dfs(s, last);
        tmpPath.pop_back();
    }
}

void Dijkstra(int s) {
    Dist[s] = 0;
    priority_queue<pqNode, vector<pqNode>, compare> pq;
    pq.push(pqNode(s, 0, s));

    while (!pq.empty()) {
        auto cur = pq.top();
        pq.pop();

        if (State[cur.destination]) {
            if (cur.dist == Dist[cur.destination])
                lastNode[cur.destination].push_back(cur.lastNode);
            continue;
        } else {
            State[cur.destination] = true;
            lastNode[cur.destination].push_back(cur.lastNode);
        }

        for (auto neighbor: graph[cur.destination]) {
            if (Dist[neighbor.first] >= Dist[cur.destination] + neighbor.second || Dist[neighbor.first] == -1) {
                Dist[neighbor.first] = Dist[cur.destination] + neighbor.second;
                pq.push(pqNode(neighbor.first, Dist[neighbor.first], cur.destination));
            }
        }
    }
}

bool pathCompare(vector<int> lhs, vector<int> rhs) {
    float l = 0, r = 0;
    for (int city: lhs) {
        l += (float)cityIndex[city];
    }
    for (int city: rhs) {
        r += (float )cityIndex[city];
    }
    l = l / (float )lhs.size();
    r = r / (float )rhs.size();
    return l <= r;
}

int main() {

    int n, m, s, t;
    cin >> n >> m >> s >> t;

    for (int i = 0; i < n; ++i) {
        cin >> cityIndex[i];
    }
    // 建图
    for (int i = 0; i < m; ++i) {
        int u, v, d;
        cin >> u >> v >> d;
        graph[u].push_back({v, d});
        graph[v].push_back({u, d});
    }

    Dijkstra(s);

    dfs(s, t);

    sort(Paths.begin(), Paths.end(), pathCompare);
    vector<int> result = Paths.front();
    reverse(result.begin(), result.end());

    cout << Dist[t] << " ";
    for (int i = 0; i < result.size(); ++i) {
        if (i != result.size() - 1) {
            cout << result[i] << "->";
        }else{
            cout << result[i] << endl;
        }
    }
    return 0;
}
相关推荐
FPGA_无线通信1 分钟前
OFDM 同步设计(3)
算法·fpga开发
SHOJYS7 分钟前
离散化+二位前缀和的计数题 [USACO20DEC] Rectangular Pasture S
算法
java修仙传14 分钟前
力扣hot100:最大子数组和
数据结构·算法·leetcode
white-persist20 分钟前
【攻防世界】reverse | Mysterious 详细题解 WP
c语言·开发语言·网络·汇编·c++·python·安全
赖small强20 分钟前
【Linux C/C++ 开发】 GCC 编译过程深度解析指南
linux·c语言·c++·预处理·链接·编译·编译过程
BestOrNothing_201521 分钟前
C++ 并发四件套:并发编程 / 原子性 / 数据竞争 / 内存模型 (全解析)
c++·多线程·并发编程·线程安全·内存模型·原子操作·数据竞争
想唱rap25 分钟前
C++之unordered_set和unordered_map
c++·算法·哈希算法
Rock_yzh29 分钟前
LeetCode算法刷题——54. 螺旋矩阵
数据结构·c++·学习·算法·leetcode·职场和发展·矩阵
shx666632 分钟前
2.1.2 ROS2 C++ 示例
c++·ros2
papership40 分钟前
【入门级-算法-5、数值处理算法:高精度整数除以单精度整数的商和余数】
算法