```java
package com.example.demo;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;
class Node {
int v;
int weight;
int money;
public Node(int v, int weight, int money) {
this.v = v;
this.weight = weight;
this.money = money;
}
}
public class A3009 {
static int k;
static int n;
static ArrayList<Node>[] G;
static boolean[] visited;
static int ans = Integer.MAX_VALUE;
static int[][] minLen; // minLen[i][j] 表示从起点到 i 点,花销为 j 的最短路的长度
static Scanner sc = new Scanner(System.in);
public static void main(String[] args) throws IOException {
k = sc.nextInt(); // k coins
n = sc.nextInt(); // n cities
int r = sc.nextInt(); // r roads 有向
G = new ArrayList[n];
for (int i = 0; i < n; i++) {
G[i] = new ArrayList<Node>();
}
visited = new boolean[n];
minLen = new int[n][k+1];
for (int i = 0; i < n; i++) {
for (int j = 0; j <= k; j++) {
minLen[i][j] = Integer.MAX_VALUE;
}
}
for (int i = 0; i < r; i++) {
int s = sc.nextInt() - 1;
int d = sc.nextInt() - 1;
int l = sc.nextInt(); // 路的长度
int t = sc.nextInt(); // 花的硬币
// 排除自环
if (s != d) {
Node e = new Node(d, l, t);
G[s].add(e);
}
}
visited[0] = true;
dfs(0, 0, 0);
if (ans == Integer.MAX_VALUE) {
System.out.println(-1);
}
else {
System.out.println(ans);
}
}
static void dfs(int v, int count, int length) {
// 到达终点
if (v == n - 1) {
ans = Math.min(ans, length);
return;
}
// 对当前这个城市 v 的能走到的下一个城市
for (Node e : G[v]) {
if (visited[e.v] == false) {
int cost = count + e.money;
// 如果花费的钱大于 k
if (cost > k) {
continue;
}
// 最优性剪枝
// 保存中间计算结果进行剪枝: 如果到达下一个城市花的钱相同但是走的路径更长
if (length + e.weight >= ans || length + e.weight >= minLen[e.v][cost]) {
continue;
}
minLen[e.v][cost] = length + e.weight; // 更新中间结果
visited[v] = true;
dfs(e.v, cost, length + e.weight);
visited[v] = false;
}
}
}
}
```javapackage com.example.demo;import java.io.IOException;import java.util.ArrayList;import java.util.Scanner;class Node { int v; int weight; int money; public Node(int v, int weight, int money) { this.v = v; this..