• Life is a Game(icpc上海站)


    这个题好啊

    为什么会想到 K r u s k a l Kruskal 重构树呢?

    我们最好情况一定是遍历完所有的点,那么最优路线一定是最小生成树

    我们能否继续到达某个点很大一部分是根据最小生成树路径上权值最大的边

    观察一波 K r u s k a l Kruskal 重构树的性质:

    边权越大的形成的点都越靠上

    当你到达了一个非叶子节点,就意味着你一定可以到达这个点子树上的所有叶子节点

    设一条边为(u,v)如果从u到v 那么一定是将u的子树全部走完了 再加上初始的k 判断能否到v

    这样对于每一条边都可以这样 对于一个点只要尽力向上就能获得尽可能大的值 但是一个点只能到他上面路径上要求最大的 不能超过初始的k

    这个可以倍增处理

    这个题一定不能正面模拟 一定出不了结果的

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    const int N = 1e6+10;
    struct Edge1{int u, v, d;}e1[N];
    int head[N << 3], idx, a[N << 1];
    struct Edge{int to, nxt;}e[N << 3];
    void add(int u, int v) {e[++idx].to = v, e[idx].nxt = head[u], head[u] = idx;}
    bool cmp(Edge1 _a, Edge1 b) {return _a.d < b.d;}
    int f[N << 1];
    int find(int n) {return n == f[n] ? n : f[n] = find(f[n]);}
    int n, m, q;
    int wi[N << 1], fa[N << 1][33], w[N << 1][33];
     
    void dfs(int u, int _f)
    {
        for (int i = head[u]; i; i = e[i].nxt) {
            int v = e[i].to;
            if (v == _f) continue;
            dfs(v, u);
            a[u] += a[v];
        }
    	fa[u][0] = _f, w[u][0] = wi[_f] - a[u];
    }
    
    void kruskal()
    {
        sort(e1 + 1, e1 + 1 + m, cmp);
        int cnt = n;
        for (int i = 1; i <= m; i++) {
            int x = e1[i].u, y = e1[i].v, d = e1[i].d;
            x = find(x), y = find(y);
            if (x == y) continue;
            cnt++;
            f[x] = cnt, f[y] = cnt;
            add(cnt, x); add(cnt, y); wi[cnt] = d;
        }
        dfs(cnt, 0);
        for (int i = 1; i <= 25; i++) {
            for (int j = 1; j <= cnt; j++) {
                fa[j][i] = fa[fa[j][i - 1]][i - 1];
                w[j][i] = max(w[j][i - 1], w[fa[j][i - 1]][i - 1]);
            }
        }
    }
    
    signed main()
    {
        cin >> n >> m >> q;
        for (int i = 1; i <= n + m; i++) f[i] = i;
        for (int i = 1; i <= n; i++) cin >> a[i];
        for (int i = 1; i <= m; i++) 
            cin >> e1[i].u >> e1[i].v >> e1[i].d;
        kruskal();
        while (q--) {
            int x, k;
            cin >> x >> k;
            for (int i = 24; i >= 0; i--) {
                if (fa[x][i]) {
                    if (w[x][i] <= k) {x = fa[x][i];}
                }
            }cout << k + a[x] << endl;
        }
        return 0;
    }
    
    
  • 相关阅读:
    HybridAPP开发框架Ionic+AngularJS+Cordova搭建
    MySQL数据类型DECIMAL用法
    RabbitMQ用户管理
    Linux中Mysql root用户看不到mysql库问题解决方式
    RabbitMQ环境安装
    RabbitMQ简介
    Mysql根据一个基库生成其他库与其不同的库升级脚本
    关于中文乱码的解决方法(URL方式)
    java反射机制
    the jar file rt.jar has no source attachment
  • 原文地址:https://www.cnblogs.com/wzxbeliever/p/16200246.html
Copyright © 2020-2023  润新知