首页 > 代码库 > 百度之星2014复赛 - 1002 - The Query on the Tree
百度之星2014复赛 - 1002 - The Query on the Tree
先上题目:
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变为根。
现在度度熊想请更聪明的你帮助解决这个问题。
有一棵树,树的每个点有点权,每次有三种操作:
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行为描述中的三种操作。
每组数据第一行为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
2014年百度之星程序设计大赛 - 复赛
中文题意不解释,思路记录每一个节点的当前父节点(根节点的父节点可记为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:\n",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\n",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 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。