zoukankan      html  css  js  c++  java
  • 2566

    #include<cstdio>
    #include<cstring>
    #include<set>
    #include<algorithm>
    #include<vector>
    
    using namespace std;
    
    const int MAX_SIZE = 12000;
    const int INF = 0x3f3f3f3f;
    
    struct Node{
        int l, r;
        Node *left, *right;
        int minn, tag;
    };
    
    Node tree[MAX_SIZE * 2 + 10]; int tn;
    
    inline void update(Node* cur, int v){
        if(cur -> tag > v){
        cur -> tag = v;
        cur -> minn = min(cur -> minn, v);
        }
    }
    
    inline void pushDown(Node* cur){
        if(cur -> tag != INF){
        if(cur -> l != cur -> r){
            update(cur -> left, cur -> tag);
            update(cur -> right, cur -> tag);
        }
        cur -> tag = INF;
        }
    }
    
    Node* build(int l, int r){
        Node* cur = tree + (tn ++);
        cur -> l = l;
        cur -> r = r;
        cur -> minn = cur -> tag = INF;
        if(l != r){
        int mid = (l + r) >> 1;
        cur -> left = build(l, mid);
        cur -> right = build(mid + 1, r);
        }
        return cur;
    }
    
    Node* sroot;
    
    struct O{
        int id, co;
    };
    
    vector<int> event[MAX_SIZE + 10];
    multiset<int> s[MAX_SIZE * 2 + 10];
    int val[MAX_SIZE * 2 + 10], vn;
    int data[MAX_SIZE + 10], n;
    int nodes[MAX_SIZE + 10], nxt[MAX_SIZE * 2 + 10], to[MAX_SIZE * 2 + 10], en;
    int len[MAX_SIZE * 2 + 10];
    int m;
    bool vis[MAX_SIZE + 10];
    int root, minn, tot, size[MAX_SIZE + 10];
    O cg[MAX_SIZE + 10];
    int dist[MAX_SIZE + 10], clist[MAX_SIZE + 10], cn;
    int cco[MAX_SIZE + 10];
    int pre[MAX_SIZE * 2 + 10], tVal[MAX_SIZE * 2 + 10];
    
    inline void addEdge(int f, int t, int w){
        ++ en;
        to[en] = t;
        len[en] = w;
        nxt[en] = nodes[f];
        nodes[f] = en;
    }
    
    void dfs(int cur, int fa){
        size[cur] = 1;
        for(int e = nodes[cur]; e; e = nxt[e]){
        if(to[e] == fa || vis[to[e]])
            continue;
        dfs(to[e], cur);
        size[cur] += size[to[e]];
        }
    }
    
    void findRoot(int cur, int fa){
        int maxn = tot - size[cur];
        for(int e = nodes[cur]; e; e = nxt[e]){
        if(to[e] == fa || vis[to[e]])
            continue;
        if(size[to[e]] > maxn)
            maxn = size[to[e]];
        findRoot(to[e], cur);
        }
        if(maxn < minn){
        minn = maxn;
        root = cur;
        }
    }
    
    void dfsDist(int cur, int fa){
        int si = (int)event[cur].size();
        for(int i = 0; i < si; i ++)
        clist[++ cn] = event[cur][i];
        cco[cur] = data[cur];
        int p = lower_bound(val, val + vn, data[cur]) - val;
        s[p].insert(dist[cur]);
        if((int)s[p].size() > 1){
        set<int>::iterator it = s[p].begin();
        int d = *it;
        ++ it;
        d += *it;
        if(tVal[p] > d)
            tVal[p] = d;
        }
        for(int e = nodes[cur]; e; e = nxt[e]){
        if(to[e] == fa || vis[to[e]])
            continue;
        dist[to[e]] = dist[cur] + len[e];
        dfsDist(to[e], cur);
        }
    }
    
    void change(Node* cur, int l, int r, int v){
        if(cur -> l == l && cur -> r == r){
        update(cur, v);
        return;
        }
        pushDown(cur);
        int mid = (cur -> l + cur -> r) >> 1;
        if(r <= mid)
        change(cur -> left, l, r, v);
        else if(l > mid)
        change(cur -> right, l, r, v);
        else{
        change(cur -> left, l, mid, v);
        change(cur -> right, mid + 1, r, v);
        }
        cur -> minn = min(cur -> left -> minn, cur -> right -> minn);
    }
    
    void clear(int cur, int fa){
        int p = lower_bound(val, val + vn, cco[cur]) - val;
        s[p].clear();
        p = lower_bound(val, val + vn, data[cur]) - val;
        change(sroot, pre[p], m, tVal[p]);
        pre[p] = 0; tVal[p] = INF;
        for(int e = nodes[cur]; e; e = nxt[e]){
        if(to[e] == fa || vis[to[e]])
            continue;
        clear(to[e], cur);
        }
    }
    
    void work(int cur){
        dfs(cur, 0);
        tot = size[cur];
        minn = INF;
        findRoot(cur, 0);
        cur = root;
        dist[cur] = 0;
        cn = 0;
        dfsDist(cur, 0);
        sort(clist + 1, clist + cn + 1);
        for(int i = 1; i <= cn; i ++){
        int t = clist[i];
        int p;
        p = lower_bound(val, val + vn, cco[cg[t].id]) - val;
        s[p].erase(s[p].find(dist[cg[t].id]));
        int d;
        if((int)s[p].size() > 1){
            set<int>::iterator it = s[p].begin();
            d = *it;
            ++ it;
            d += *it;
        } else
            d = INF;
        if(pre[p] != t){
            change(sroot, pre[p], t - 1, tVal[p]);
            pre[p] = t;
            tVal[p] = d;
        } else
            tVal[p] = min(tVal[p], d);
        cco[cg[t].id] = cg[t].co;
        p = lower_bound(val, val + vn, cco[cg[t].id]) - val;
        s[p].insert(dist[cg[t].id]);
        if((int)s[p].size() > 1){
            set<int>::iterator it = s[p].begin();
            d = *it;
            ++ it;
            d += *it;
        } else
            d = INF;
        if(pre[p] != t){
            change(sroot, pre[p], t - 1, tVal[p]);
            pre[p] = t;
            tVal[p] = d;
        } else
            tVal[p] = min(tVal[p], d);
        }
        //   s[0].clear();
        for(int i = 1; i <= cn; i ++){
        int t = clist[i];
        int p = lower_bound(val, val + vn, cg[t].co) - val;
        change(sroot, pre[p], m, tVal[p]);
        pre[p] = 0;
        tVal[p] = INF;
        }
        clear(cur, 0);
        vis[cur] = true;
        for(int e = nodes[cur]; e; e = nxt[e]){
        if(!vis[to[e]])
            work(to[e]);
        }
    }
    
    void print(Node* cur){
        if(cur -> l == cur -> r){
        if(cur -> minn == INF)
            printf("-1
    ");
        else
            printf("%d
    ", cur -> minn);
        return;
        }
        pushDown(cur);
        print(cur -> left);
        print(cur -> right);
    }
    
    int main(){
    #ifndef ONLINE_JUDGE
        freopen("test.in", "r", stdin);
        freopen("test.out", "w", stdout);
    #endif
        scanf("%d", &n);
        for(int i = 1; i <= n; i ++){
        scanf("%d", data + i);
        val[vn ++] = data[i];
        }
        for(int i = 1; i < n; i ++){
        int a, b, w;
        scanf("%d%d%d", &a, &b, &w);
        addEdge(a, b, w);
        addEdge(b, a, w);
        }
        scanf("%d", &m);
        for(int i = 1; i <= m; i ++){
        scanf("%d%d", &cg[i].id, &cg[i].co);
        event[cg[i].id].push_back(i);
        val[vn ++] = cg[i].co;
        }
        sort(val, val + vn);
        vn = unique(val, val + vn) - val;
        sroot = build(0, m);
        memset(tVal, INF, sizeof(tVal));
        work(1);
        for(int i = 0; i < vn; i ++)
        s[0].insert(INF);
        memset(pre, INF, sizeof(pre));
        print(sroot);
    //    printf("%d
    ", pre[2]);
    
        return 0;
    }
    View Code
  • 相关阅读:
    Python 生成器相关知识
    openpyxl 模块学习记录
    Python 装饰器相关知识
    Python 闭包的相关知识
    Python 内置函数简单介绍
    Git提交的本地仓库在什么位置
    支付宝公钥,私钥加密解密问题
    字符转义
    pyhton 模拟浏览器实现
    大小端模式 大端存储 小端存储
  • 原文地址:https://www.cnblogs.com/zhonghaoxi/p/4167861.html
Copyright © 2011-2022 走看看