穷游?“穷”游?

Description

贫穷的小A有一个梦想,就是到t国去一次穷游,但现实是残酷的。小A所在的世界一共有n(n<=500)个国家,国家与国家之间总共有E(E<=50000)条道路相连,第i个国家对于进入它的外国人都要收取Bi的费用,而小A家住在s国,他必须通过这些道路在各个国家之间中转最终到达t国(除非他运气够好可以直接从s国到达t国)。但是贫穷的小A只剩下M(M<=100)元家底了,因此他必须精打细算旅途的费用,同时小A对于t国实在太向往了,因此他希望能够走最短的路尽快到达t国。这个问题难倒了小A,现在他请你帮他算一算他到达t国的最短路径有多长。

Input

第一行输入T(T<=10)表示有T组数据。每组数据第一行输入n、E、s、t、M,分别表示小A所在世界的国家数、国家之间的总道路数、小A的国籍、小A向往的国家以及小A的家底;接下来一行输入n个正整数Bi,表示第i个国家收取的过路费(由于小A是s国人,因此s国不会收取,但t国会);接下来输入E行每行三个正整数u(1<=u<=n)、v(1<=v<=n)、w,表示u国和v国之间存在着一条长度为w的无向边(可能有重边)。输入保证最终结果不会使int溢出。

Output

输出T行正整数,第i行表示第i组数据小A花费不超过M元到达t国的最短路。若小A无法到达t国,输出-1.

Sample Input

3
2 2 1 2 10
20 10
1 2 1
1 2 2
3 1 1 3 10
1 1 1
2 3 1
3 3 1 3 10
1 11 1
1 2 1
1 2 3
2 3 1

Sample Output

1
-1
-1

#include <iostream>
#include <vector>
#include <queue>
#include <climits>
using namespace std;

struct Node {
    int cost;       // 距离
    int country;    // 到达了哪个国家
    int spent;      // 花费了多少钱
    Node(int c, int co, int s) : cost(c), country(co), spent(s) {}
    bool operator>(const Node& other) const {
        return cost > other.cost;
    }
};

typedef pair<int, int> pii;

vector<vector<int>> dijkstra(vector<vector<pii>>& graph, int start, int max_cost, vector<int>& countries) {
    int n = graph.size();
    vector<vector<int>> dist(n+1, vector<int>(max_cost + 1, INT_MAX));
    dist[start][0] = 0;
    priority_queue<Node, vector<Node>, greater<Node>> pq;
    pq.push(Node(0, start, 0));

    while (!pq.empty()) {
        int cost = pq.top().cost;
        int u = pq.top().country;
        int spent = pq.top().spent;
        pq.pop();
        if (cost > dist[u][spent]) continue;
        for (auto edge : graph[u]) {
            int v = edge.first;
            int w = edge.second;
            int new_spent = spent + countries[v];
            if (new_spent <= max_cost && cost + w < dist[v][new_spent]) {
                dist[v][new_spent] = cost + w;
                pq.push(Node(dist[v][new_spent], v, new_spent));
            }
        }
    }

    return dist;
}

int main() {
    int T;
    cin >> T;
    while (T--) {
        int n, E, s, t, M;
        cin >> n >> E >> s >> t >> M;
        vector<int> countries(n);
        for (int i = 0; i < n; i++) {
            cin >> countries[i];
        }
        vector<vector<pii>> graph(n);
        for (int i = 0; i < E; i++) {
            int u, v, w;
            cin >> u >> v >> w;
            graph[u-1].push_back({v-1, w});
            graph[v-1].push_back({u-1, w});
        }

        vector<vector<int>> dist = dijkstra(graph, s-1, M, countries);
        int min_cost = INT_MAX;
        for (int spent = 0; spent <= M; spent++) {
            min_cost = min(min_cost, dist[t-1][spent]);
        }
        if (min_cost == INT_MAX) {
            cout << -1 << endl;
        } else {
            cout << min_cost << endl;
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云风Com

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值