• 【SPOJ Query on a tree 】 (树链剖分)


    http://acm.hust.edu.cn/vjudge/problem/13013

    题意:

    有一棵N个节点的树(1<=N<=10000),N-1条边,边的编号为1~N-1,每条边有一个权值,要求模拟两种操作:

    1:QUERY x y 求节点x和节点y之间的路径中权值最大的边。

    2:CHANGE p k修改第p条边的权值为k。

     

    【分析】

      树链剖分裸题。。

      【表示我一开始怎么TLE,后来怎么AC的并不知道。。

     

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<set>
      7 using namespace std;
      8 #define Maxn 10010
      9 #define INF 0x7fffffff
     10 
     11 int mymax(int x,int y) {return x>y?x:y;}
     12 
     13 struct node
     14 {
     15     int x,y,c,next;
     16 }t[2*Maxn];int len;
     17 
     18 int first[Maxn];
     19 void ins(int x,int y,int c)
     20 {
     21     t[++len].x=x;t[len].y=y;t[len].c=c;
     22     t[len].next=first[x];first[x]=len;
     23 }
     24 
     25 char s[110];
     26 
     27 int son[Maxn],dfn[Maxn],top[Maxn],cnt;
     28 int sm[Maxn],fa[Maxn],id[Maxn],dep[Maxn];
     29 void dfs1(int x,int f)
     30 {
     31     dep[x]=dep[f]+1;
     32     sm[x]=1;son[x]=0;fa[x]=f;
     33     for(int i=first[x];i;i=t[i].next) if(t[i].y!=f)
     34     {
     35         int y=t[i].y;
     36         dfs1(y,x);
     37         sm[x]+=sm[y];
     38         if(son[x]==0||sm[son[x]]<sm[y]) son[x]=y;
     39     }
     40 }
     41 
     42 void dfs2(int x,int tp)
     43 {
     44     dfn[x]=++cnt;top[x]=tp;
     45     if(son[x]) dfs2(son[x],tp);
     46     for(int i=first[x];i;i=t[i].next) if(t[i].y!=fa[x]&&t[i].y!=son[x])
     47      dfs2(t[i].y,t[i].y);
     48 }
     49 
     50 struct nnode
     51 {
     52     int l,r,lc,rc,mx;
     53 }tr[2*Maxn];int tot;
     54 
     55 int build(int l,int r)
     56 {
     57     int x=++tot;
     58     tr[x].l=l;tr[x].r=r;
     59     int mid=(l+r)>>1;
     60     if(l!=r)
     61     {
     62         tr[x].lc=build(l,mid);
     63         tr[x].rc=build(mid+1,r);
     64     }
     65     tr[x].mx=-INF;
     66     return x;
     67 }
     68 
     69 void change(int x,int y,int z)
     70 {
     71     if(tr[x].l==tr[x].r)
     72     {
     73         tr[x].mx=z;
     74         return;
     75     }
     76     int mid=(tr[x].l+tr[x].r)>>1;
     77     if(y<=mid) change(tr[x].lc,y,z);
     78     else change(tr[x].rc,y,z);
     79     tr[x].mx=mymax(tr[tr[x].lc].mx,tr[tr[x].rc].mx);
     80 }
     81 
     82 int query(int x,int l,int r)
     83 {
     84     if(tr[x].l==l&&tr[x].r==r) return tr[x].mx;
     85     int mid=(tr[x].l+tr[x].r)>>1;
     86     if(r<=mid) return query(tr[x].lc,l,r);
     87     else if(l>mid) return query(tr[x].rc,l,r);
     88     return mymax(query(tr[x].lc,l,mid),query(tr[x].rc,mid+1,r));
     89 }
     90 
     91 int get_ans(int x,int y)
     92 {
     93     int mx=0;
     94     while(top[x]!=top[y])
     95     {
     96         if(dep[top[x]]<dep[top[y]]) swap(x,y);
     97         mx=mymax(mx,query(1,dfn[top[x]],dfn[x]));
     98         x=fa[top[x]];
     99     }
    100     if(x==y) return mx;
    101     if(dep[x]>dep[y]) swap(x,y);
    102     mx=mymax(mx,query(1,dfn[x]+1,dfn[y]));
    103     return mx;
    104 }
    105 
    106 int main()
    107 {
    108     int T;
    109     scanf("%d",&T);
    110     while(T--)
    111     {
    112         int n;
    113         scanf("%d",&n);
    114         len=0;
    115         memset(first,0,sizeof(first));
    116         for(int i=1;i<n;i++)
    117         {
    118             int x,y,c;
    119             scanf("%d%d%d",&x,&y,&c);
    120             ins(x,y,c);ins(y,x,c);
    121         }
    122         dep[0]=0;dfs1(1,0);
    123         cnt=0;dfs2(1,1);
    124         tot=0;build(1,n);
    125         for(int i=1;i<=len;i+=2)
    126         {
    127             if(fa[t[i].x]==t[i].y) id[(i+1)/2]=t[i].x;
    128             else id[(i+1)/2]=t[i].y;
    129             change(1,dfn[id[(i+1)/2]],t[i].c);
    130         }
    131         while(1)
    132         {
    133             scanf("%s",s);
    134             if(s[0]=='D') break;
    135             int x,y;
    136             scanf("%d%d",&x,&y);
    137             if(s[0]=='C')
    138             {
    139                 change(1,dfn[id[x]],y);
    140             }
    141             else
    142             {
    143                 printf("%d
    ",get_ans(x,y));
    144             }
    145         }
    146     }
    147     return 0;
    148 }
    View Code

    2017-01-21 11:45:00

     

  • 相关阅读:
    如何正确夸奖孩子
    C# datatable分页和 list 分页
    js修改Switchery复选框的状态
    虚拟机中centos中设置固定IP
    CommonJS和ES6
    npm使用淘宝镜像
    RabbitMQ基础概念详细介绍
    Web漏洞扫描神器Nikto使用指南
    Redis基本使用
    ROS文件系统导览
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6336738.html
Copyright © 2020-2023  润新知