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;
}

上一篇:数据结构与算法——堆 的优先队列


下一篇:LeetCode 23. 合并K个排序链表