zoukankan      html  css  js  c++  java
  • 百度之星2014复赛

    先上题目:

    The Query on the Tree

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 54    Accepted Submission(s): 18


    Problem Description
      度度熊最近沉迷在和树有关的游戏了,他一直认为树是最神奇的数据结构。一天他遇到这样一个问题:
      有一棵树,树的每个点有点权,每次有三种操作:
      1. Query x 表示查询以x为根的子树的权值和。
      2. Change x y 表示把x点的权值改为y(0<=y<=100)。
      3. Root x 表示把x变为根。
      现在度度熊想请更聪明的你帮助解决这个问题。
     
    Input
      第一行为数据组数T(1 <= T <= 100)
      每组数据第一行为N(1<= N <= 10000),表示树的节点数。
      后面N-1行每行有两个数x,y ,表示x,y之间有一条边 1<=x,y<=N。初始时树是以1号节点为根节点。
      之后的一行为N个数表示这N个点的点权(点权的范围是0到100)。
      然后为整数Q(Q<=1000)为操作次数。
      之后的Q行为描述中的三种操作。
     
    Output
      对于第k组输入数据,第一行输出Case #k 接下来对于每个”Query x”操作,输出以x为根的子数和。
     
    Sample Input
    2
    5
    1 2
    1 3
    3 4
    3 5
    1 2 3 4 5 5
    Query 1
    Change 3 10
    Query 1
    Root 4
    Query 3
    8
    1 2
    1 3
    3 4
    4 5
    5 6
    5 7
    4 8
    1 2 3 4 5 6 7 8
    5
    Query 1
    Query 3
    Root 5
    Query 3
    Query 1
     
    Sample Output
    Case #1:
    15
    22
    18
    Case #2:
    36
    33
    6
    3
     
    Source
     

      中文题意不解释,思路记录每一个节点的当前父节点(根节点的父节点可记为0) ,然后对于三种操作,如果是修改某个结点的值,那就修改完这个值以及当前节点的子树的值以后,向父节点方向修改每一个节点的子树的值;如果是修改根节点,那就从新根节点开始向父节点方向移动,将遇到的节点的父节点都改成向新根节点方向,同时更新子树的最值;如果是查询的话,就直接输出。需要注意的是既的更新父节点以及子树的权值。

    上代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <utility>
     4 #define MAX 10002
     5 using namespace std;
     6 typedef pair<int,int> pii;
     7 
     8 int n,tot;
     9 int p[MAX];
    10 int fa[MAX];
    11 int w[MAX];
    12 int s[MAX];
    13 pii e[MAX<<1];
    14 char q[10];
    15 bool f;
    16 
    17 void reset(){
    18     memset(p,-1,sizeof(int)*(n+1));
    19     tot=0;
    20 }
    21 
    22 void add(int u,int v){
    23     e[tot].first=v; e[tot].second=p[u]; p[u]=tot++;
    24     e[tot].first=u; e[tot].second=p[v]; p[v]=tot++;
    25 }
    26 
    27 int deal(int u,int t){
    28     int c=0;
    29     s[u]=0;
    30     fa[u]=t;
    31     for(int v=p[u];v!=-1;v=e[v].second){
    32         if(e[v].first!=t){
    33             c = deal(e[v].first,u);
    34             s[u]+=c;
    35         }
    36     }
    37     s[u]+=w[u];
    38     return s[u];
    39 }
    40 
    41 void C(int a,int v){
    42     int c = w[a];
    43     while(a!=0){
    44         s[a] = s[a] - c + v;
    45         a = fa[a];
    46     }
    47 }
    48 
    49 void R(int r,int t){
    50     s[r]=0;
    51     for(int i=p[r];i!=-1;i=e[i].second){
    52         if(e[i].first==t) continue;
    53         if(e[i].first==fa[r]) R(fa[r],r);
    54         s[r]+=s[e[i].first];
    55         fa[e[i].first]=r;
    56     }
    57     s[r]+=w[r];
    58 }
    59 
    60 int main()
    61 {
    62     int t,u,v,a,m;
    63     //freopen("data.txt","r",stdin);
    64     scanf("%d",&t);
    65     for(int z=1;z<=t;z++){
    66         printf("Case #%d:
    ",z);
    67         scanf("%d",&n);
    68         reset();
    69         for(int i=1;i<n;i++){
    70             scanf("%d %d",&u,&v);
    71             add(u,v);
    72         }
    73         for(int i=1;i<=n;i++) scanf("%d",&w[i]);
    74         deal(1,0);
    75         scanf("%d",&a);
    76         while(a--){
    77             scanf("%s %d",q,&m);
    78             if(q[0]=='Q'){
    79                 printf("%d
    ",s[m]);
    80             }else if(q[0]=='C'){
    81                 scanf("%d",&v);
    82                 C(m,v);
    83                 w[m]=v;
    84             }else{
    85                 R(m,0);
    86                 fa[m]=0;
    87             }
    88         }
    89     }
    90     return 0;
    91 }
    1002
  • 相关阅读:
    hdu 2485 Destroying the bus stations 迭代加深搜索
    hdu 2487 Ugly Windows 模拟
    hdu 2492 Ping pong 线段树
    hdu 1059 Dividing 多重背包
    hdu 3315 My Brute 费用流,费用最小且代价最小
    第四天 下载网络图片显示
    第三天 单元测试和数据库操作
    第二天 布局文件
    第一天 安卓简介
    Android 获取存储空间
  • 原文地址:https://www.cnblogs.com/sineatos/p/3762800.html
Copyright © 2011-2022 走看看