SPOJ 375 Query on a tree 新手题

来源:互联网 发布:淘宝皇冠店年入多少 编辑:程序博客网 时间:2024/05/17 12:46

题目链接:http://www.spoj.com/problems/QTREE/


You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1.

We will ask you to perfrom some instructions of the following form:

  • CHANGE i ti : change the cost of the i-th edge to ti
    or
  • QUERY a b : ask for the maximum edge cost on the path from node a to node b

Input

The first line of input contains an integer t, the number of test cases (t <= 20). t test cases follow.

For each test case:

  • In the first line there is an integer N (N <= 10000),
  • In the next N-1 lines, the i-th line describes the i-th edge: a line with three integersa b c denotes an edge betweena, b of costc (c <= 1000000),
  • The next lines contain instructions "CHANGE i ti" or "QUERY a b",
  • The end of each test case is signified by the string "DONE".

There is one blank line between successive tests.

Output

For each "QUERY" operation, write one integer representing its result.

Example

Input:131 2 12 3 2QUERY 1 2CHANGE 1 3QUERY 1 2DONEOutput:13不错的讲解:http://blog.sina.com.cn/s/blog_7a1746820100wp67.html还有这个PPT做的也不错:http://wenku.baidu.com/link?url=sUIv5dWxARQ3VwDcXgRh10WjpvsM3ImhEw4ocFzeVNLkbVyFhVubRMnCGHq_GH4I_k-HC-62bi5Sh3oQtA9ld3bhvfXxUUYmpfzvLrxAv0K代码:
#include <algorithm>#include <cstdlib>#include <iostream>#include <cstring>#include <cstdio>#include <vector>#include <cctype>#include <cmath>#include <stack>#include <queue>#include <list>#include <map>#include <set>using namespace std;#define min2(x, y)     min(x, y)#define max2(x, y)     max(x, y)#define min3(x, y, z)  min(x, min(y, z))#define max3(x, y, z)  max3(x, max(y, z))#define clr(x, y)      memset(x, y, sizeof(x))#define scf(n)         scanf("%d", &n)#define scf2(n,m)      scanf("%d %d",&n,&m)#define scf3(n,m,p)    scanf("%d %d %d",&n,&m,&p)#define scfs(ch)       scanf("%s",ch)#define ptf(n)         printf("%d",n)#define ptfs(s)        printf("%s",s)#define ptln()         printf("\n")#define ptk()          printf(" ")#define ptc(c)         printf("%c",c)#define LL long long#define pi acos(-1.0)#define inf 1 << 31-1#define eps 0.00001#define maxn  10005#define maxm  20005#define mod 10000007int fa[maxn],dep[maxn],siz[maxn],son[maxn],top[maxn],maxv[maxn*4],val[maxn],tid[maxn];int head[maxn];int edge = 0, label = 0;int n;struct node{    int v,next;}e[maxm];struct Edge{    int a, b, c;    Edge(){};    Edge(int a, int b, int c):a(a),b(b),c(c){}}E[maxn];void init(){   edge = 0;   label = 0;   clr(head, -1);   clr(fa, 0);   clr(son, 0);   clr(siz, 0);   clr(dep, 0);}/*void find_heavy_edge(int x,int father = 0)  //找重边{    fa[x] = father;    dep[x] = dep[father] + 1;    siz[x] = 1;    int maxsize = 0;    for(int i = head[x]; i != -1; i = e[i].next)    {        int child = e[i].v;        if(child == father) continue;        find_heavy_edge(child, x);        siz[x] += siz[child];        if(siz[child] > maxsize)            {                maxsize = siz[child];                son[x] = child;            }    }}*/void find_heavy_edge(int x, int father, int depth)  //找重边{    fa[x] = father;    dep[x] = depth;    siz[x] = 1;    int maxsize = 0;    son[x] = 0;    for(int i = head[x]; i != -1; i = e[i].next)    {        int child = e[i].v;        if(child == father)            continue;        find_heavy_edge(child, x, depth+1);        siz[x] += siz[child];        if(siz[child] > maxsize)        {            maxsize = siz[child];            son[x] = child;        }    }}void add_edge(int x, int y){    e[edge].v = y;    e[edge].next = head[x];    head[x] = edge++;}void connect_heavy_edge(int x, int ancestor) //连重边成重链{    tid[x] = ++label;     //每条边新编号    top[x] = ancestor;    if(son[x] != 0)       //沿重边向下拉成重链        connect_heavy_edge(son[x], ancestor);    for(int i = head[x]; i != -1; i = e[i].next)    {        int child = e[i].v;        if(child != son[x] && child != fa[x]) //不在当前重链上,自己单独拉成链        connect_heavy_edge(child, child);    }}void build_tree(int rt, int l, int r)  //建树{    if(l == r)    {        maxv[rt] = val[l];        return;    }    int m = (l + r) / 2;    build_tree(rt*2, l, m);    build_tree(rt*2+1,m+1,r);    maxv[rt] = max(maxv[rt*2], maxv[rt*2+1]);}/*void change_it(int rt, int L, int R, int tid, int d){     while (  L != R ) {            int m = (L + R) / 2;            rt <<= 1 ;            if ( tid <= m ) R = m ;            else {                L = m + 1 ;                rt |= 1 ;            }        }        maxv[rt] = d ;        while ( rt != 1 ) {            rt >>= 1 ;            maxv[rt] = max ( maxv[rt*2] , maxv[rt*2+1] ) ;        }}*/void change_it(int rt, int L, int R, int tid, int d) //线段树的更新{    if(tid < L || tid > R)  return ;    if(L == R)    {        maxv[rt] = d;        return;    }    int m = (L + R) / 2;    change_it(rt*2, L, m, tid, d);    change_it(rt*2+1, m+1, R, tid, d);    maxv[rt] = max(maxv[rt*2], maxv[rt*2+1]);}int query_it(int rt, int L, int R, int l, int r)  //线段树的查询{    if(l <= L && r >= R) return maxv[rt];    int m = (L + R) / 2;    if(r <= m)        return query_it(rt*2,L,m,l,r);    if(m < l)        return query_it(rt*2+1,m+1,R,l,r);    return max(query_it(rt*2,L,m,l,r),query_it(rt*2+1,m+1,R,l,r));}int query(int x, int y)    //重难点{    int res = 0;    while(top[x] != top[y])    {        if(dep[top[x]] < dep[top[y]])            swap(x, y);        res = max(res, query_it(1, 1, n, tid[top[x]], tid[x]));        x = fa[top[x]];    }    if(x == y)  return res;    if(dep[x] > dep[y])        swap(x, y);     return max(res, query_it(1, 1, n, tid[x]+1, tid[y]));}void solve(){    char ch[10];    int a, b, c;    init();    scf(n);    for(int i = 1; i < n; i++)    {        scf3(a, b, c);        E[i] = Edge(a, b, c);        add_edge(a, b);        add_edge(b, a);    }    find_heavy_edge(1, 1, 1);    connect_heavy_edge(1, 1);    for(int i = 1; i < n; i++)    {        int a = E[i].a;        int b = E[i].b;        if(dep[a] < dep[b])            swap(a, b);        val[tid[a]] = E[i].c;    }    build_tree(1, 1, n);    while(~scfs(ch) && ch[0] != 'D')    {        scf2(a, b);        if(ch[0] == 'Q')            printf("%d\n", query(a, b));        else if(ch[0] == 'C')        {            int aa = E[a].a;            int bb = E[a].b;            if(dep[aa] < dep[bb])                swap(aa, bb);            change_it(1, 1, n, tid[aa], b);        }    }}int main(){    //freopen("in.txt","r",stdin);    int t;    scf(t);    while(t--)    {        solve();    }    return 0;}


 
0 0
原创粉丝点击