spoj 375 Query on a tree

题目传送门

题目大意:给一个n个结点的树以及它的n-1条边,两个操作:1、更改其中的边权。2、询问结点a到b的路径中最大的边权值

 

有两篇讲得很好的博客

 http://blog.sina.com.cn/s/blog_6974c8b20100zc61.html

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

另外还有一篇论文:http://wenku.baidu.com/view/8861df38376baf1ffc4fada8

 

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 10005
#define lson i<<1,l,m
#define rson i<<1|1,m+1,r
struct Edge
{
    int v,next;
} edge[maxn<<1];
int tree[maxn],T, n, tot,cnt,a,b,e[maxn][3],head[maxn], dep[maxn], id[maxn], fa[maxn], top[maxn], son[maxn], num[maxn];
char s[10];
void add(int a, int b)
{
    edge[++cnt].v = b;
    edge[cnt].next = head[a];
    head[a] = cnt;
}
void dfs(int v)
{
    num[v] = 1,son[v] = 0;
    for (int i = head[v]; i ; i = edge[i].next)
        if (edge[i].v != fa[v])
        {
            fa[edge[i].v] = v;
            dep[edge[i].v] = dep[v]+1;
            dfs(edge[i].v);
            if (num[edge[i].v] > num[son[v]]) son[v] = edge[i].v;
            num[v] += num[edge[i].v];
        }
}
void dfs2(int v, int tp)
{
    id[v] = ++tot,top[v] = tp;
    if (son[v] != 0) dfs2(son[v], top[v]);
    for (int i = head[v]; i > 0; i = edge[i].next)
        if (edge[i].v != son[v] && edge[i].v != fa[v])
            dfs2(edge[i].v, edge[i].v);
}

void update(int i, int l, int r, int k, int x)
{
    if (k > r || l > k) return;
    if (l == r)
    {
        tree[i] = x;
        return;
    }
    int m = (l + r)>>1;
    update(lson, k, x);
    update(rson, k, x);
    tree[i] = max(tree[i<<1], tree[i<<1|1]);
}

int query(int i, int l, int r, int L, int R)
{
    if (L> r || R < l) return 0;
    if (L<= l && r <= R) return tree[i];
    int m = (l + r)>>1;
    return max(query(lson,L, R), query(rson, L,R));
}
int find(int va, int vb)
{
    int f1 = top[va], f2 = top[vb], ans = 0;
    while (f1 != f2)
    {
        if (dep[f1] < dep[f2])
        {
            swap(f1, f2);
            swap(va, vb);
        }
        ans = max(ans, query(1, 1, tot, id[f1], id[va]));
        va = fa[f1];
        f1 = top[va];
    }
    if (va == vb) return ans;
    if (dep[va] > dep[vb]) swap(va, vb);
    return max(ans, query(1, 1, tot, id[son[va]], id[vb]));  //
}
int main()
{
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d", &n);
        fa[1] = tot = dep[1] = cnt = 0;
        memset(num, 0, sizeof(num));
        memset(head, 0, sizeof(head));
        memset(tree, 0, sizeof(tree));
        for (int i = 1; i < n; i++)
        {
            scanf("%d%d%d", &e[i][0], &e[i][1], &e[i][2]);
            add(e[i][0],e[i][1]);
            add(e[i][1],e[i][0]);
        }
        dfs(1);
        dfs2(1,1);
        for (int i = 1; i < n; i++)
        {
            if (dep[e[i][0]] > dep[e[i][1]]) swap(e[i][0], e[i][1]);
            update(1, 1, tot, id[e[i][1]], e[i][2]);
        }
        while(scanf("%s",s)==1)
        {
            if(s[0]=='D') break;
            scanf("%d%d",&a,&b);
            if(s[0]=='Q') printf("%d\n",find(a,b));
            else update(1,1,tot,id[e[a][1]],b);
        }
    }
    return 0;
}


 

 

 

你可能感兴趣的:(spoj 375 Query on a tree)