AcWing 903. 昂贵的聘礼 解题报告
题目链接
以每个人为结点,他们之间交易的代价为距离建图,跑最短路即可。其中特别要注意的是最短路径上的任何两个人的等级差都要 \(< m\)。我们可以根据酋长的等级来枚举等级的上下界。
/*
@Author: nonameless
@Date: 2020-06-04 17:14:22
@Email: 2835391726@qq.com
@Blog: https://www.cnblogs.com/nonameless/
*/
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
#define sz(x) (int)x.size()
#define all(x) x.begin(), x.end()
using namespace std;
typedef long long ll;
typedef pair<ll, ll> PLL;
typedef pair<int, int> PII;
const double eps = 1e-8;
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const ll LNF = 0x3f3f3f3f3f3f;
inline int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
inline ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
inline int lcm(int a, int b) { return a * b / gcd(a, b); }
const int N = 110, M = N * N;
int n, m;
int P[N], L[N];
int idx = 0;
int h[N], to[M], w[M], nxt[M];
int dist[N], vis[N];
void add(int a, int b, int c){
to[ ++ idx] = b; w[idx] = c; nxt[idx] = h[a]; h[a] = idx;
}
int dijkstra(int l, int r){
memset(vis, 0, sizeof vis);
memset(dist, INF, sizeof dist);
dist[1] = 0;
priority_queue<PII, vector<PII>, greater<PII> > pq;
pq.push({dist[1], 1});
while(!pq.empty()){
PII cur = pq.top(); pq.pop();
int u = cur.y, d = cur.x;
if(vis[u]) continue;
vis[u] = 1;
for(int i = h[u]; i; i = nxt[i]){
int v = to[i];
if(L[v] >= l && L[v] <= r){
if(dist[v] > d + w[i]){
dist[v] = d + w[i];
pq.push({dist[v], v});
}
}
}
}
int res = INF;
for(int i = 1; i <= n; i ++) res = min(res, dist[i] + P[i]);
return res;
}
int main(){
cin >> m >> n;
for(int i = 1; i <= n; i ++){
int p, l, x;
scanf("%d%d%d", &p, &l, &x);
P[i] = p; L[i] = l;
for(int j = 1; j <= x; j ++){
int t, v;
scanf("%d%d", &t, &v);
add(i, t, v);
}
}
int ans = INF;
for(int l = L[1] - m; l <= L[1]; l ++){
int r = l + m;
ans = min(ans, dijkstra(l, r));
}
cout << ans << endl;
return 0;
}