spoj 375 Query on a tree 链路剖分模板
来源:互联网 发布:windows经典桌面图片 编辑:程序博客网 时间:2024/06/06 00:16
在大神的看了下。,然后自己写了一下,对于链路剖分还是比较模式化的 边权型160++
#include<cstdio>#include<cstring>#include<iostream>#define M 20000#define lson (rt<<1)#define rson (rt<<1|1)#define inf 0x3f3f3f3fusing namespace std;struct G{ int head[M],en; struct E{ int u,v,next,cost; }e[M<<2]; void init(){ memset(head,-1,sizeof(head));en=0; } void add(int u,int v,int cost){ e[en].u=u;e[en].v=v;e[en].cost=cost;e[en].next=head[u];head[u]=en++; }}g1;struct T{ struct E{ int l,r,tmax; }e[M<<2]; int value[M]; void push_up(int rt){ e[rt].tmax=max(e[lson].tmax,e[rson].tmax); } void build(int l,int r,int rt){ e[rt].l=l;e[rt].r=r;e[rt].tmax=0; if(l==r){ e[rt].tmax=value[l]; return ; } int mid=(l+r)>>1; build(l,mid,lson); build(mid+1,r,rson); push_up(rt); } void update(int ul,int new_flag,int rt){ if(e[rt].l==ul&&e[rt].r==ul){ e[rt].tmax=new_flag; return ; } int mid=(e[rt].l+e[rt].r)>>1; if(ul<=mid) update(ul,new_flag,lson); else update(ul,new_flag,rson); push_up(rt); } int query(int ul,int ur,int rt){ if(ul<=e[rt].l&&ur>=e[rt].r){ return e[rt].tmax; } int mid=(e[rt].l+e[rt].r)>>1; if(ur<=mid) return query(ul,ur,lson); else if(ul>mid) return query(ul,ur,rson); else{ int t1=query(ul,ur,lson); int t2=query(ul,ur,rson); return max(t1,t2); } }}tr;int my_que[M<<2],top[M],son[M],en,sz[M],fa[M],dep[M],hash[M],value[M];void build_tree(){ int l=0,r=-1; my_que[++r]=1; dep[1]=1; sz[0]=0; fa[1]=0; while(l<=r){ int u=my_que[l++];son[u]=0;sz[u]=1; for(int i=g1.head[u];i!=-1;i=g1.e[i].next){ int v=g1.e[i].v; if(v==fa[u]) continue; fa[v]=u; value[v]=g1.e[i].cost; dep[v]=dep[u]+1; my_que[++r]=v; } } for(int i=r;i>=0;i--){ int u=my_que[i]; for(int j=g1.head[u];j!=-1;j=g1.e[j].next){ int v=g1.e[j].v; if(v==fa[u]) continue; sz[u]+=sz[v]; if(sz[son[u]]<sz[v]) son[u]=v; } } for(int i=0;i<=r;i++){ int u=my_que[i]; if(son[fa[u]]==u) top[u]=top[fa[u]]; else top[u]=u; }}void re_build(int n){ en=1; for(int i=1;i<=n;i++){ if(top[i]!=i) continue; hash[i]=en; tr.value[en++]=value[i]; for(int j=i;j;j=son[j]){ if(son[j]==0) continue; hash[son[j]]=en; tr.value[en++]=value[son[j]]; } } tr.build(1,en,1);}void work(int n){ build_tree(); re_build(n);}void change(int l,int new_flag){ int u=g1.e[(l<<1)-1].u; int v=g1.e[(l<<1)-1].v; if(dep[v]<dep[u]) swap(u,v); tr.update(hash[v],new_flag,1);}int query(int x,int y){ int ans=-inf; while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]]) swap(x,y); ans=max(ans,tr.query(hash[top[x]],hash[x],1)); x=fa[top[x]]; } if(x==y) return ans; if(dep[y]<dep[x]) swap(x,y); ans=max(ans,tr.query(hash[son[x]],hash[y],1)); return ans;}int main(){ int cas;while(~scanf("%d",&cas)){ while(cas--){ int n;scanf("%d",&n); g1.init(); for(int i=0;i<n-1;i++){ int u,v,cost;scanf("%d%d%d",&u,&v,&cost); g1.add(u,v,cost); g1.add(v,u,cost); } work(n); char str[100]; while(1){ scanf("%s",str); if(str[0]=='D') break; if(str[0]=='C'){ int t1,t2;scanf("%d%d",&t1,&t2); change(t1,t2); } if(str[0]=='Q'){ int t1,t2;scanf("%d%d",&t1,&t2); int ans=query(t1,t2); printf("%d\n",ans); } } } } return 0;}/*1141 2 91 3 71 4 12 5 132 6 106 11 116 12 123 7 84 8 64 9 24 10 59 13 313 14 4*/
- spoj 375 Query on a tree 链路剖分模板
- 【树链剖分模板】【SPOJ 375】 Query on a tree
- spoj 375 Query on a tree 树剖模板
- [SPOJ 375]Query on a tree(树剖模板)
- [SPOJ 375]Query On a Tree(树链剖分)
- spoj 375--Query On a Tree [树链剖分]
- spoj 375 Query on a tree 树链剖分
- spoj 375 Query on a tree
- SPOJ 375 Query on a tree
- SPOJ 375 Query on a tree(树链剖分)
- SPOJ 375 Query on a tree
- SPOJ Query on a tree
- SPOJ Query on a tree
- SPOJ Query on a tree
- Query on a tree SPOJ
- Query on a tree SPOJ
- spoj Query on a tree(树链剖分模板题)
- SPOJ QTREE Query on a tree(边权LCT模板)
- 信息检索中的结果评价
- Mac OS X:“安全启动”和“安全模式”是什么?
- C/C++中.bss段的解释
- EXHPROF
- 文本压缩理论简介
- spoj 375 Query on a tree 链路剖分模板
- 第十周contest(2)
- java汉字编码
- 窗口关闭setDefaultCloseOperation()的整理
- Gallery
- 一种高效快速的高密度椒盐噪声消除算法(吕宗伟等)
- 浅析java字符编码(在socket游走之间)
- 焦点移到编辑框后让里面内容默认选中,还原从eclipse里拉出来的独立窗口
- Linux C++ 程序内存布局