You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

72 lines
2.3 KiB

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> 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<PII, vector<PII>, greater<PII>> 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;
}