# 23. 毕业旅行[200分]
# 题目内容
四年校园时光即将结束,小明和室友计划一次难忘的毕业旅行。他们准备从 A 城市出发,前往他们已经久仰的 B 城市。两座城市之间有多种出行方案,既可直达,也可途经其他城市中转,每条路线的费用不相同。请帮助他们在预算 w 内,找到花费最少的路线。
# 输入描述
第一行有三个整数 n, m, w:
n:城市数量,2 ≤ n ≤ 100m:路线数量,1 ≤ m ≤ 1000w:最大预算,1 ≤ w ≤ 10^5
接下来是一个二维数组,记录了所有的路线信息。每条路线有 3 个整数 u, v, cost:
u:起点城市,1 ≤ u ≤ nv:终点城市,1 ≤ v ≤ ncost:所需费用,1 ≤ cost ≤ 10^5
# 输出描述
若存在满足预算的最优路线,返回最小花费;若不存在,则返回 -1。
补充说明:
- 出发城市编号为 1,目的地城市编号为 n 所代表的值。
- 每条路线的起点和终点都不相同(u ≠ v),且只能单方向通行(u → v,不能 v → u)。
- 从城市 u 到城市 v,不存在多条不同费用的路线。
# 样例
# 样例 1
输入
3 3 10
1 2 5
2 3 5
1 3 8
1
2
3
4
2
3
4
输出
8
1
说明:
- 直达:城市 1 → 城市 3,花费 8,在预算内最优。
- 中转:途经城市 2,花费 5 + 5 = 10,费用更高。
# 样例 2
输入
4 4 20
1 2 5
2 3 5
3 4 5
1 4 25
1
2
3
4
5
2
3
4
5
输出
15
1
说明:
- 直达:城市 1 → 城市 4,花费 25,超出预算。
- 中转:路径 1 → 2 → 3 → 4,花费 15,为最小可行方案。
# 样例 3
输入
3 3 5
1 2 3
2 3 3
1 3 10
1
2
3
4
2
3
4
输出
-1
1
说明: 所有可行路径都超过预算 5,返回 -1 表示无解。
# 代码
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
let inputs = [];
rl.on('line', (input) => {
inputs.push(input);
});
rl.on('close', () => {
const [n, m, w] = inputs[0].split(' ').map(Number);
const list = [];
inputs.forEach((item, index) => {
if (index > 0) {
list.push(item.split(' ').map(Number));
}
});
// console.log(n, m, w, list);
const used = Array(m).fill(false);
let best = Infinity;
const dfs = (x, nums) => {
if (nums > w) return;
if (nums > best) return;
if (x === n) {
// console.log(nums);
best = Math.min(best, nums);
return;
}
for (let i = 0; i < list.length; i++) {
let [u, v, cost] = list[i];
if (u === x && !used[i]) {
used[i] = true;
nums += cost;
dfs(v, nums);
used[i] = false;
nums -= cost;
}
}
};
dfs(1, 0);
console.log(best === Infinity ? '-1' : best);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
← 22. 受限序列重排 24. 统计特殊数字 →