ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

HDU多校第五场 P7187(分层图建虚拟原点)

2022-08-05 12:32:55  阅读:163  来源: 互联网

标签:std HDU dist vert int 第五场 多校 depth ver


Slipper

&ebsp; 题意: 我们知道有\(n\)个节点,有\(n - 1\)条边,所有的点形成了一棵树,每一个点到下一个点都有代价\(cc\),我们也有一个操作,可以将满足\(\left\vert depth_i - depth_j\right\vert = k\)的所有点联通,连起来的新的边的代价是\(c\),要我们求从出发点到目的地的最小代价是多少。
  思路:因为不太好处理\(\left\vert depth_i - depth_j\right\vert = k\)这个条件,那我们就要选择将每一个深度都建出一个分层图,然后再每一个分层图中都建立两个虚拟原点,分别连向所有满足\(\left\vert depth_i - depth_j\right\vert = k\)的所有点。这样我们只需要用\(dijkstra\)跑一遍就可以求出答案了。

i64 w[N * 3];
int ne[N * 3], e[N * 3], h[N * 3];
i64 dist[N * 3];
int dep[N];
bool st[N * 3];

void solve() {
    int n, m, c;
    scanf("%d", &n);
        
    int mxd = 0, idx = 0;
    
    for (int i = 0; i <= n + 2; i ++ ) dep[i] = 0;

    for (int i = 0; i <= 3 * n + 10; i ++ )
        h[i] = -1, st[i] = 0, dist[i] = MX;
    
    auto add = [&] (int a, int b, i64 v) {
        w[idx] = v, e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
    };
    
    for (int i = 1; i < n; i ++ ) {
        int u, v;
        i64 cc;
        scanf("%d%d%lld", &u, &v, &cc);
        add(u, v, cc);
        add(v, u, cc);
    }

    scanf("%d%d", &m, &c);    

    std::function<void(int, int, int)> dfs1 = [&] (int u, int fa, int depth) {  
        dep[u] = depth;    
        mxd = std::max(mxd, depth);
        for (int i = h[u]; ~i; i = ne[i]) {
            int v = e[i];
            if (v == fa) continue;
            dfs1(v, u, depth + 1);
        }
    };

    dfs1(1, 0, 1);
    std::vector<int> G[mxd + m + 1];

    for (int i = 1; i <= n; i ++ ) {
        G[dep[i]].push_back(i);
    }

    for (int i = 1; i <= mxd; i ++ ) {
        for (auto& adj : G[i]) add(adj, 1 + n + i, c);
        for (auto& adj : G[i + m]) add(n + i + 1, adj, 0);
        for (auto& adj : G[i]) add(n * 2 + i + 1, adj, 0);
        for (auto& adj : G[i + m]) add(adj, 1 + n * 2 + i, c);
    }
    
    int s, d;
    scanf("%d%d", &s, &d);

    auto dijkstra = [&] () -> i64 {
        dist[s] = 0;
        std::priority_queue<std::pair<i64, int>, std::vector<std::pair<i64, int>>, std::greater<std::pair<i64, int>>> q;
        q.push(std::make_pair(0, s));

        while(q.size()) {
            std::pair<i64, int> t = q.top();
            q.pop();
            int ver = t.second;
            if (st[ver]) continue;
            st[ver] = true;

            for (int i = h[ver]; ~i; i = ne[i]) {
                int v = e[i];
                if (dist[v] > dist[ver] + w[i]) {
                    dist[v] = dist[ver] + w[i];
                    q.push({dist[v], v});
                }
            }
        }
        return dist[d] == MX ? -1 : dist[d];
    };
    printf("%lld\n", dijkstra());
}

标签:std,HDU,dist,vert,int,第五场,多校,depth,ver
来源: https://www.cnblogs.com/Haven-/p/16553899.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有