SPOJ 375 树链剖分
来源:互联网 发布:编程时间和水平成正比 编辑:程序博客网 时间:2024/05/22 06:29
思路:
链剖裸题……
//By SiriusRen#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define N 22222char ch[11];int n,cases,root,tree[N*4],xx,yy,ans;int tot,first[N],next[N],v[N],w[N];int cnt,top[N],deep[N],size[N],son[N],rec[N],f[N];struct Edge{int from,to,weight;}edge[N];void add(int x,int y,int z){ w[tot]=z,v[tot]=y; next[tot]=first[x],first[x]=tot++;}void dfs(int x,int fa){ size[x]=1;son[x]=0; for(int i=first[x];~i;i=next[i]){ if(v[i]==fa)continue; f[v[i]]=x; deep[v[i]]=deep[x]+1; dfs(v[i],x); size[x]+=size[v[i]]; if(size[v[i]]>size[son[x]])son[x]=v[i]; }}void dfs2(int x,int fa,int tp){ rec[x]=++cnt;top[x]=tp; if(son[x])dfs2(son[x],x,tp); for(int i=first[x];~i;i=next[i]) if(v[i]!=son[x]&&v[i]!=fa)dfs2(v[i],x,v[i]);}void insert(int l,int r,int pos){ if(l==r){tree[pos]=yy;return;} int mid=(l+r)>>1; if(mid<xx)insert(mid+1,r,pos<<1|1); else insert(l,mid,pos<<1); tree[pos]=max(tree[pos<<1],tree[pos<<1|1]);}int query(int l,int r,int pos,int Left,int Right){ if(l>=Left&&r<=Right)return tree[pos]; int mid=(l+r)>>1; if(mid<Left)return query(mid+1,r,pos<<1|1,Left,Right); else if(mid>=Right)return query(l,mid,pos<<1,Left,Right); else return max(query(l,mid,pos<<1,Left,Right),query(mid+1,r,pos<<1|1,Left,Right));}void find(){ int fx=top[xx],fy=top[yy]; while(fx!=fy){ if(deep[fx]<deep[fy])swap(xx,yy),swap(fx,fy); ans=max(ans,query(1,n,1,rec[fx],rec[xx])); xx=f[fx];fx=top[xx]; } if(xx==yy)return; if(deep[xx]>deep[yy])swap(xx,yy); ans=max(ans,query(1,n,1,rec[son[xx]],rec[yy]));}int main(){ scanf("%d",&cases); while(cases--){ memset(tree,0,sizeof(tree)); memset(size,0,sizeof(size)); memset(first,-1,sizeof(first)); scanf("%d",&n); for(int i=1;i<n;i++){ scanf("%d%d%d",&edge[i].from,&edge[i].to,&edge[i].weight); add(edge[i].from,edge[i].to,edge[i].weight); add(edge[i].to,edge[i].from,edge[i].weight); } root=(n+1)>>1; f[root]=deep[root]=cnt=tot=0; dfs(root,root),dfs2(root,root,root); for(int i=1;i<n;i++){ if(deep[edge[i].from]>deep[edge[i].to])swap(edge[i].from,edge[i].to); xx=rec[edge[i].to],yy=edge[i].weight; insert(1,cnt,1); } while(scanf("%s",ch)&&ch[0]!='D'){ scanf("%d%d",&xx,&yy); if(ch[0]=='Q')ans=0,find(),printf("%d\n",ans); else xx=rec[edge[xx].to],insert(1,n,1); } }}
0 0
- spoj 375 (树链剖分)
- SPOJ 375 树链剖分
- 【转】SPOJ 375 树链剖分
- spoj 375 树链剖分模板
- SPOJ 375 树链剖分学习
- SPOJ 375 树链剖分
- SPOJ 375 树链剖分
- SPOJ 375 树链剖分
- SPOJ 375 树链剖分
- 树链剖分模板(spoj 375)
- 树链剖分(SPOJ 375)
- LCT spoj 375 树链剖分
- SPOJ 375 (树链剖分+线段树)
- SPOJ 375 (树链剖分+线段树)
- Spoj 375 QTREE(树链剖分)
- spoj 375
- [SPOJ 375]Query On a Tree(树链剖分)
- Spoj 375 Qtree 树链剖分 + 线段树 解法
- Map的keySet方法理解
- 根据手机sim卡获取运营商信息
- ASP.NET MVC入门(二)---MVC数据传递
- leetcode:Binary Search Tree:Contains Duplicate III(220)
- matlab读取arff格式文件前的环境配置工作
- SPOJ 375 树链剖分
- MTK GM2.0
- MySQL两行数据合并一行sql
- 测试Python是否安装成功
- Maven - 构建生命周期
- 新人首发
- ajax-jq-php(mysql)四级省市级联
- java字节码文件 helloworld
- Git workflow 选型分析