#include using namespace std; typedef pair PII; const int N = 110; const int M = N * N; // 边数最多有n^2,这是顶天设置,此处与传统的题目不,一般的M= N<<1,此题目没有明确给出边数上限,直接认为N^2 const int INF = 0x3f3f3f3f; int h[N], e[M], ne[M], w[M], idx; void add(int a, int b, int c) { e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++; } int dis[N]; // 单源最短路径 bool st[N]; // 配合Dijkstra用的是否出队过 int L[N]; // 每个节点的等级 int n, m; // n个物品,m表示等级差距限制 int dijkstra(int l, int r) { memset(dis, 0x3f, sizeof dis); memset(st, 0, sizeof st); priority_queue, greater> q; // 距离,节点号 q.push({0, 0}); // 超级源点 dis[0] = 0; while (q.size()) { auto t = q.top(); q.pop(); int u = t.second; if (st[u]) continue; st[u] = true; for (int i = h[u]; ~i; i = ne[i]) { int v = e[i]; // 枚举边时,只处理等级在指定范围内 if (L[v] < l || L[v] > r) continue; if (dis[v] > dis[u] + w[i]) { dis[v] = dis[u] + w[i]; q.push({dis[v], v}); } } } return dis[1]; } int main() { memset(h, -1, sizeof h); // 初始化邻接表 cin >> m >> n; // m:表示地位等级差距限制,n:物品的总数 for (int i = 1; i <= n; i++) { // 枚举每个节点 int p, l, cnt; // 价格 等级 替代品数目 cin >> p >> L[i] >> cnt; add(0, i, p); // 虚拟源点0, 0获取i号物品,需要p这么多的金币 while (cnt--) { // 读入物品i的替代品 int u, v; // 替代品的编号 和 优惠价格 cin >> u >> v; // u:替代品编号,v:收到替代品后的收费价格 add(u, i, v); // 从替代品向可替代品引一条长度为v的边 } } // 预求最小,先设最大 int res = INF; // 枚举区间范围进行多次求最小路径 for (int i = L[1] - m; i <= L[1]; i++) res = min(res, dijkstra(i, i + m)); // 输出结果 cout << res << endl; return 0; }