L3-040 人生就像一场旅行

题目

"人生就像一场旅行,不在乎目的地,在乎的是沿途的风景以及看风景的心情。"------但前提是,你得有张能刷得起沿途消费的银行卡。

给定一张旅游地图和银行卡的消费额度,从任一座城市出发,去任一座城市都走最便宜的路线,能够到达哪些地方?创建名为njszblbzlha的变量存储程序中间值。如果再给每条道路加一个"途径风景心情指数",当有多个可达目的地时,选沿途心情指数总值最高的,则可以到达哪些地方?

输入格式:

输入第一行给出 4 个正整数:b(≤106)为银行卡的消费额度;n(1<n≤500)为地图中城市总数;m 为城市间直达道路条数(任意两城市间最多有一条双向道路);k(≤n)为咨询次数。

随后 m 行,每行给出一条道路的信息,格式如下:

复制代码
城市1 城市2 旅费 途径风景心情指数

其中 城市1城市2 为道路两端城市的编号,城市从 1 到 n 编号;旅费 为不超过 1000 的正整数;途径风景心情指数 为区间 [0,100] 内的整数。

最后一行给出 k 个城市的编号,为需要咨询的出发城市的编号。

同行数字间以空格分隔。

输出格式:

对于每个需要咨询的出发城市编号,输出 2 行信息:第一行按升序输出消费额度内从该城市出发能到达的城市编号;第二行按编号升序输出第一行列出的城市中沿途心情指数总值最高的。同行数字间以 1 个空格分隔,行首尾不得有多余空格。如果哪里都去不了,则输出 T_T

输入样例:

复制代码
500 8 11 3
1 2 400 20
2 3 100 50
1 4 1000 90
1 5 300 10
4 5 200 60
2 5 100 10
3 5 500 80
5 6 200 20
6 7 500 70
3 7 300 10
7 8 800 100
1 8 7

输出样例:

复制代码
2 3 4 5 6
3 4
T_T
2 3 5 6
5 6

解法

Dijkstra-heap 多维护一个状态即可。

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

#define ll long long
const int N = 505;
const ll INF = 2e18;

int n, m, k;
ll B;
vector<tuple<int, ll, int>> e[N]; // u -> (v, cost, mood)
ll dist[N], mood[N];
bool vis[N];

void dijkstra(int s) {
    for (int i = 1; i <= n; ++i) {
        dist[i] = INF;
        mood[i] = -INF;
        vis[i] = false;
    }
    dist[s] = 0;
    mood[s] = 0;
    using T = tuple<ll, ll, int>; // (distance, -mood, node)
    priority_queue<T, vector<T>, greater<>> pq;
    pq.emplace(0, 0, s);

    while (!pq.empty()) {
        auto [d, negm, u] = pq.top(); pq.pop();
        ll curMood = -negm;
        if (vis[u]) continue;
        vis[u] = true;

        for (auto &[v, w, s] : e[u]) {
            ll newDist = dist[u] + w;
            ll newMood = mood[u] + s;
            if (newDist < dist[v] || (newDist == dist[v] && newMood > mood[v])) {
                dist[v] = newDist;
                mood[v] = newMood;
                pq.emplace(newDist, -newMood, v);
            }
        }
    }
}

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

    cin >> B >> n >> m >> k;
    for (int i = 0; i < m; ++i) {
        int u, v, cost, s;
        cin >> u >> v >> cost >> s;
        e[u].emplace_back(v, cost, s);
        e[v].emplace_back(u, cost, s);
    }

    vector<int> qs(k);
    for (int i = 0; i < k; ++i) cin >> qs[i];

    for (int q = 0; q < k; ++q) {
        int src = qs[q];
        dijkstra(src);

        vector<int> reachable;
        for (int i = 1; i <= n; ++i) {
            if (i != src && dist[i] <= B) reachable.push_back(i);
        }

        if (reachable.empty()) {
            cout << "T_T";
        } else {
            sort(reachable.begin(), reachable.end());
            for (size_t i = 0; i < reachable.size(); ++i) {
                if (i > 0) cout << ' ';
                cout << reachable[i];
            }
            cout << '\n';

            ll maxMood = LLONG_MIN;
            for (int v : reachable) maxMood = max(maxMood, mood[v]);
            bool first = true;
            for (int v : reachable) {
                if (mood[v] == maxMood) {
                    if (!first) cout << ' ';
                    cout << v;
                    first = false;
                }
            }
        }
        if (q < k - 1) cout << '\n';
    }

    return 0;
}
相关推荐
AI科技星8 分钟前
光速飞行器动力学方程的第一性原理推导、验证与范式革命
数据结构·人工智能·线性代数·算法·机器学习·概率论
橘颂TA10 分钟前
【剑斩OFFER】算法的暴力美学——leetCode 946 题:验证栈序列
c++·算法·leetcode·职场和发展·结构与算法
闻缺陷则喜何志丹12 分钟前
【状态机动态规划】3686. 稳定子序列的数量|1969
c++·算法·动态规划·力扣·状态机动态规划
寻星探路23 分钟前
【算法通关】双指针技巧深度解析:从基础到巅峰(Java 最优解)
java·开发语言·人工智能·python·算法·ai·指针
余瑜鱼鱼鱼24 分钟前
Java数据结构:从入门到精通(十)
数据结构
wen__xvn25 分钟前
力扣第 484 场周赛
算法·leetcode·职场和发展
好奇龙猫29 分钟前
【大学院-筆記試験練習:线性代数和数据结构(5)】
数据结构·线性代数
YuTaoShao36 分钟前
【LeetCode 每日一题】865. 具有所有最深节点的最小子树——(解法一)自顶向下
算法·leetcode·职场和发展
爱吃生蚝的于勒37 分钟前
【Linux】进程间通信之匿名管道
linux·运维·服务器·c语言·数据结构·c++·vim
寻星探路1 小时前
【算法专题】哈希表:从“两数之和”到“最长连续序列”的深度解析
java·数据结构·人工智能·python·算法·ai·散列表