spoj 375 Query on the tree [树链剖分]

来源:互联网 发布:cms管理系统 工作流 编辑:程序博客网 时间:2024/06/05 04:31

这个题是树链剖分中的入门题吧

题意:

给你n个点的一棵树,然后会后两个操作,1是修改边的权值,2是查询从a到b所经过的最大边权是多少

由于操作数相当的多,所以不能够暴力做


首先什么是树链剖分

其实就是通过讲一棵树拆分成多条链然后将链对应的放到一个数据结构上(例如线段树,树状数组等),然后通过对该数据结构的操作的一种思想吧


对于本题参考

点击打开链接


#include <iostream>#include <stdio.h>#include <algorithm>#include <string.h>using namespace std;struct Node{int num,next,v;}edge[20001];struct Node1{int x,y,v;}a[10001];int max(int x,int y){if(x<y) return y;else return x;}int cnt;int siz[10001],dep[10001],fa[10001],son[10001],topfa[10001],id[10001],num[10001],head[10001];void add(int x,int y){edge[cnt].num=y;edge[cnt].next=head[x];head[x]=cnt++;edge[cnt].num=x;edge[cnt].next=head[y];head[y]=cnt++;}void dfs1(int a,int f,int d){siz[a]=1;dep[a]=d;fa[a]=f;son[a]=0;for(int i=head[a];i!=-1;i=edge[i].next){int v=edge[i].num;if(v==f) continue;dfs1(v,a,d+1);siz[a]+=siz[v];if(siz[v]>siz[son[a]])  son[a]=v;}}int nu;void dfs2(int a,int f){topfa[a]=f;id[a]=++nu;if(son[a]) dfs2(son[a],f);for(int i=head[a];i!=-1;i=edge[i].next){int v=edge[i].num;if(v==son[a]) continue;else if(v==fa[a]) continue;else dfs2(v,v);}}struct Tree{int l,r,max;}t[40001];void build(int l ,int r,int x){int ls=x<<1,rs=ls|1;//cout << l<<" " << r << " " << x << " " << ls << " " << rs<< endl;t[x].l=l;t[x].r=r;if(l==r) { t[x].max=num[l];return;}int mid=(l+r)/2;build(l,mid,ls);build(mid+1,r,rs);t[x].max=max(t[ls].max,t[rs].max);}void change(int l,int v,int x){//cout << l  <<" " << v <<" " << x<< endl;if(l==t[x].l&&l==t[x].r) {t[x].max=v; return;}int ls=x<<1,rs=ls|1;int mid=(t[x].l+t[x].r)/2;if(l<=mid) change(l,v,ls);else change(l,v,rs);t[x].max=max(t[ls].max,t[rs].max);}void swap(int &x,int &y){int a=x;x=y;y=a;}int query_tree(int l,int r,int x){if(l>r) return 0;int ls=x<<1,rs=ls|1;if(t[x].l==l&&t[x].r==r) return t[x].max;int mid=(t[x].l+t[x].r)>>1;int res=0;if(mid>=r) res=max(res,query_tree(l,r,ls));else if(mid+1<=l) res=max(res,query_tree(l,r,rs)); else res=max(query_tree(l,mid,ls),query_tree(mid+1,r,rs));return res;}int query(int x,int y){if(dep[x]>dep[y]) swap(x,y);if(topfa[x]==topfa[y])  return query_tree(id[x]+1,id[y],1);if(dep[topfa[x]]<dep[topfa[y]]) swap(x,y);return max(query_tree(id[topfa[x]],id[x],1),query(fa[topfa[x]],y));}char s[10];int n,x,y;int main(){int T;scanf("%d",&T);while(T--){scanf("%d",&n);cnt=0;nu=0;memset(head,-1,sizeof(head));for(int i=1;i<n;i++){scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].v);add(a[i].x,a[i].y);}dfs1(1,0,1);dfs2(1,1);num[1]=0;for(int i=1;i<n;i++){if(a[i].x==fa[a[i].y]) {num[id[a[i].y]]=a[i].v;swap(a[i].x,a[i].y);}else num[id[a[i].x]]=a[i].v;}/*for(int i=1;i<=n;i++){printf("num:%d\n",num[i]);printf("fa:%d\n",fa[i]);printf("dep:%d\n",dep[i]);printf("siz:%d\n",siz[i]);printf("topfa:%d\n",topfa[i]);printf("id:%d\n\n",id[i]);}build(1,n,1);for(int i=1;i<=2*n;i++){printf("%d :\n",i);printf("l:%d\n",t[i].l);printf("r:%d\n",t[i].r);printf("max:%d\n",t[i].max);puts("");}*/build(1,n,1);while(1){scanf("%s",&s);if(s[0]=='D') break;scanf("%d%d",&x,&y);if(s[0]=='Q'){printf("%d\n",query(x,y));}else{//cout << x << " " <<id[a[x].x] << endl;change(id[a[x].x],y,1);}}}}



0 0
原创粉丝点击