zoukankan      html  css  js  c++  java
  • 题解【POJ1062】昂贵的聘礼

    题面

    比较复杂的最短路模型转换。

    我们考虑一种建图方式:

    • 建立一个超级源点 (S),它向每一个节点连一条权值为那一个节点物品价值的边,表示直接购买那一个物品;
    • 对于每一个节点,由它每一个可用的替代品向它连一条权值为当前替代品“优惠价格”的边,表示使用那一个替代品来购买当前物品。
    • 最终答案即为 (S)(1) 号节点的最短距离。

    考虑等级限制,我们可以枚举当前最低的等级,然后在进行松弛操作的时候判断一下当前节点是否在当前等级限制之内。每一次跑完最短路后将答案与当前的 (dist_1)( ext{min})

    注意从 (0) 开始枚举最低等级。

    #include <iostream>
    #include <cstring>
    #include <queue>
    
    using namespace std;
    
    const int N = 103, M = 20003;
    
    int n, m;
    int grade[N]; //每个物品的等级
    int tot, head[N], ver[M], nxt[M], edge[M];
    int dist[N], vis[N];
    int S;
    
    inline void add(int u, int v, int w)
    {
        ver[++tot] = v, edge[tot] = w, nxt[tot] = head[u], head[u] = tot;
    }
    
    inline void Dij(int s/*起点*/, int t/*终点*/, int LowGrade/*当前的最低等级*/, int HighGrade/*当前的最高等级*/)
    {
        memset(dist, 0x3f, sizeof dist);
        priority_queue <pair <int, int> > q;
        dist[S] = 0;
        memset(vis, 0, sizeof vis);
        q.push(make_pair(0, S));
        while (!q.empty())
        {
            int u = q.top().second; q.pop();
            vis[u] = 0;
            for (int i = head[u]; i; i = nxt[i])
            {
                int v = ver[i], w = edge[i];
                if (grade[v] < LowGrade || grade[v] > HighGrade) continue; //不满足当前的等级限制
                if (dist[v] > dist[u] + w)
                {
                    dist[v] = dist[u] + w;
                    if (!vis[v])
                        vis[v] = 1,
                        q.push(make_pair(-dist[v], v));
                }
            }
        }
    }
    
    int main()
    {
        cin >> m >> n;
        S = n + 1; //超级源点
        for (int i = 1; i <= n; i+=1)
        {
            int u = i, v, w, x;
            cin >> w >> grade[i] >> x;
            add(S, u, w); //向超级源点连一条权值为物品价格的边
            for (int j = 1; j <= x; j+=1)
                cin >> v >> w,
                add(v, u, w); //由替代品向当前物品连边
        }
        int ans = 2000000007;
        for (int nowLowGrade = 0; nowLowGrade <= n; nowLowGrade+=1) //枚举最低等级,注意要从 0 开始
        {
            Dij(S, 1, nowLowGrade, nowLowGrade + m); //跑一次 Dijkstra 最短路
            ans = min(ans, dist[1]); //将答案取最小值
        }
        cout << ans << endl;
        return 0;
    }
    
  • 相关阅读:
    spring/spirng boot添加fluent日志-aop
    python添加fluent日志记录
    springboot添加fluent日志记录
    istio添加Fluentd
    linux通过speedtest-cli测试服务器网速
    linux 发送Post请求 json格式
    springboot添加fluent日志记录
    virtaulbox docker虚拟机使用主机代理shandowsocks
    istio-jaeger-python调用链配置
    计算机网络和因特网
  • 原文地址:https://www.cnblogs.com/xsl19/p/12376535.html
Copyright © 2011-2022 走看看