zoukankan      html  css  js  c++  java
  • SPOJ

    题目链接:

    http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=13013

    题意:

    给你一颗树,现在有两个操作,一种是改变某条边的权值,一种是查询点u到v之间的路径的最大边权。

    题解:

    树链剖分入门题。

    我看的一些博客:

    http://www.tuicool.com/articles/ee2QZf6

    http://blog.csdn.net/y990041769/article/details/40348013

    http://www.cnblogs.com/lidaxin/p/5184627.html

    ppt:http://wenku.baidu.com/view/a088de01eff9aef8941e06c3.html

    树链剖分只是把一些点映射到一个区间(一个重链相当于映射到了一个区间,轻链这是映射到了孤立的一些点),然后需要线段树或者rmq之类的数据结构基础来维护一些值。

    主要代码就是两个dfs加一个solve(查询函数),两个dfs其实都挺简单的,中点把查询方法掌握了就基本ok了。

    代码:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<utility>
    using namespace std;
    
    const int maxn = 22222;
    const int INF = 0x3f3f3f3f;
    
    struct Edge {
        int u, v, w;
    }egs[maxn];
    
    vector<pair<int, int> > G[maxn];
    
    int val[maxn], fat[maxn], dep[maxn], siz[maxn], son[maxn], top[maxn], id[maxn];
    int n;
    
    //求val,fat,dep,siz,son;
    void dfs(int u, int f, int d, int va) {
        val[u] = va; fat[u] = f; dep[u] = d; siz[u] = 1;
        int ma = -INF;
        for (int i = 0; i < G[u].size(); i++) {
            int v = G[u][i].first;
            if (v == f) continue;
            dfs(v, u, d + 1, G[u][i].second);
            siz[u] += siz[v];
            if (ma < siz[v]) {
                son[u] = v; ma = siz[v];
            }
        }
    }
    //求top,id
    int _tot;
    void dfs2(int u, int f, int t) {
        top[u] = t; id[u] = ++_tot;
        if (son[u]) dfs2(son[u], u, t);
        for (int i = 0; i < G[u].size(); i++) {
            int v = G[u][i].first;
            if (v == f || v == son[u]) continue;
            //轻链的下端点top等于它自己
            dfs2(v, u, v);
        }
    }
    
    #define lson (o<<1)
    #define rson ((o<<1)|1)
    #define M (l+(r-l)/2)
    int maxv[maxn << 2];
    
    int _p, _v;
    void update(int o, int l, int r) {
        if (l == r) {
            maxv[o] = _v;
        }
        else {
            if (_p <= M) update(lson, l, M);
            else update(rson, M + 1, r);
            maxv[o] = max(maxv[lson], maxv[rson]);
        }
    }
    
    int ql, qr, _max;
    void query(int o, int l, int r) {
        if (ql <= l&&r <= qr) {
            _max = max(_max, maxv[o]);
        }
        else {
            if (ql <= M) query(lson, l, M);
            if (qr > M) query(rson, M + 1, r);
        }
    }
    
    //
    int solve(int u, int v) {
        int f1 = top[u], f2 = top[v];
        int ret = -INF;
        while (f1 != f2) {
            //printf("f1:%d,f2:%d
    ", f1, f2);
            if (dep[f1] < dep[f2]) {
                swap(f1, f2);
                swap(u, v);
            }
            ql = id[f1], qr = id[u], _max = -INF;
            query(1, 1, n);
            ret = max(ret, _max);
            u = fat[f1];
            f1 = top[u];
        }
        //printf("u:%d,v:%d
    ", u, v);
        if (u == v) return ret;
        if (dep[u] > dep[v]) swap(u, v);
        ql = id[son[u]], qr = id[v], _max = -INF;
        query(1, 1, n);
        ret = max(ret, _max);
        return ret;
    }
    
    void init() {
        for (int i = 1; i <= n; i++) G[i].clear();
        memset(son, 0, sizeof(son));
        _tot = 0;
    }
    
    int main() {
        int tc;
        scanf("%d", &tc);
        while (tc--) {
            scanf("%d", &n);
            init();
            for (int i = 1; i < n; i++) {
                scanf("%d%d%d", &egs[i].u, &egs[i].v, &egs[i].w);
                G[egs[i].u].push_back(make_pair(egs[i].v, egs[i].w));
                G[egs[i].v].push_back(make_pair(egs[i].u, egs[i].w));
            }
            dfs(1, -1, 1, -INF);
            dfs2(1, -1, 1);
            //for (int i = 1; i <= n; i++) printf("id:%d
    ", id[i]);
            for (int i = 1; i <= n; i++) {
                _p = id[i], _v = val[i];
                update(1, 1, n);
            }
            char cmd[11];
            int x, y;
            while (scanf("%s", cmd) == 1) {
                if (cmd[0] == 'D') break;
                scanf("%d%d", &x, &y);
                if (cmd[0] == 'Q') {
                    printf("%d
    ", solve(x, y));
                }
                else if (cmd[0] == 'C') {
                    int t = fat[egs[x].v] == egs[x].u ? egs[x].v : egs[x].u;
                    _p = id[t], _v = y;
                    update(1, 1, n);
                }
            }
            if(tc) puts("");
        }
        return 0;
    }
    
    /*
    4
    1 2 1
    1 3 2
    3 4 3
    QUERY 1 2
    QUERY 1 3
    QUERY 3 4
    DONE
    */
  • 相关阅读:
    在mac上搭建python环境
    iOS开发-你真的会用SDWebImage?(转发)
    iOS tableview 优化总结
    Masonry 实现输入框随键盘位置改变
    sudo 权限问题
    nodejs save遇到的一个坑
    iOS app的webview注入JS遇到的坑
    HW18-广搜
    HW17-深搜
    HW16-动归2
  • 原文地址:https://www.cnblogs.com/fenice/p/5538809.html
Copyright © 2011-2022 走看看