先上题目:
Time Limit: 2000/1000 MS
(Java/Others) Memory Limit: 32768/32768 K
(Java/Others)
Total Submission(s): 54 Accepted
Submission(s): 18
中文题意不解释,思路记录每一个节点的当前父节点(根节点的父节点可记为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 }
百度之星2014复赛 - 1002 - The Query on the Tree,布布扣,bubuko.com
百度之星2014复赛 - 1002 - The Query on the Tree
原文:http://www.cnblogs.com/sineatos/p/3762800.html