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

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