spoj 375 Query on a tree(树链剖分,线段树)
2016-02-07 11:53
459 查看
Query on a tree
Submit StatusDescriptionYou are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, 3...N-1.We will ask you to perfrom some instructions of the following form:CHANGE i ti : change the cost of the i-th edge to ti
orQUERY a b : ask for the maximum edge cost on the path from node a to node b
【思路】树链剖分。划分轻重链,线段树维护。这里有个知识入门:http://blog.sina.com.cn/s/blog_6974c8b20100zc61.html【代码】
Time Limit: 851MS | Memory Limit: 1572864KB | 64bit IO Format: %lld & %llu |
orQUERY a b : ask for the maximum edge cost on the path from node a to node b
Input
The first line of input contains an integer t, the number of test cases (t <= 20). t test cases follow.For each test case:In the first line there is an integer N (N <= 10000),In the next N-1 lines, the i-th line describes the i-th edge: a line with three integers a b c denotes an edge between a, b of cost c (c <= 1000000),The next lines contain instructions "CHANGE i ti" or "QUERY a b",The end of each test case is signified by the string "DONE".There is one blank line between successive tests.Output
For each "QUERY" operation, write one integer representing its result.Example
Input: 1 3 1 2 1 2 3 2 QUERY 1 2 CHANGE 1 3 QUERY 1 2 DONE Output: 1 3
【思路】树链剖分。划分轻重链,线段树维护。这里有个知识入门:http://blog.sina.com.cn/s/blog_6974c8b20100zc61.html【代码】
#include<cstdio> #include<vector> #include<cstring> #include<algorithm> #include<iostream> using namespace std; const int N = 20000+10; struct Edge { int u,v,w; }; vector<int> G ; vector<Edge> es; int n,z,root,d [3]; int fa ,siz ,dep ,son ,w ,top ; //fa为父节点 siz为子树大小 dep为节点深度 //son代表重儿子 w为u与fa[u]在线段树中的位置 top代表所属重链的顶端 //z为线段树大小 void adde(int u,int v,int w) { es.push_back((Edge){u,v,w}); int m=es.size(); G[u].push_back(m-1); } void dfs(int u) { //->siz[] son[] fa[] siz[u]=1; son[u]=0; for(int i=0;i<G[u].size();i++) { int v=es[G[u][i]].v; if(v!=fa[u]) { fa[v]=u; dep[v]=dep[u]+1; dfs(v); if(siz[v]>siz[son[u]]) son[u]=v; siz[u]+=siz[v]; } } } void build_tree(int u,int tp) { //son[] -> top[] w[] w[u]=++z; top[u]=tp; if(son[u]) build_tree(son[u],top[u]); for(int i=0;i<G[u].size();i++) { int v=es[G[u][i]].v; if(v!=son[u] && v!=fa[u]) build_tree(v,v); } } int tree ; void update(int u,int L,int R,int loc,int x) { if(loc<L || R<loc) return ; if(L==R) { tree[u]=x; return ; } int M=L+(R-L)/2 , lc=u*2,rc=lc+1; update(lc,L,M,loc,x); update(rc,M+1,R,loc,x); tree[u]=max(tree[lc],tree[rc]); } int query(int u,int L,int R,int l,int r) { if(R<l || L>r) return 0; if(l<=L && R<=r) return tree[u]; int M=L+(R-L)/2; return max(query(u*2,L,M,l,r),query(u*2+1,M+1,R,l,r)); } int find(int u,int v) { int f1=top[u] , f2=top[v] , ans=0; while(f1!=f2) { //直到移动到同一重链 if(dep[f1]<dep[f2]) swap(f1,f2) , swap(u,v); ans=max(ans,query(1,1,z,w[f1],w[u])); //在重链上移动同时统计 u=fa[f1] , f1=top[u]; } if(u==v) return ans; if(dep[u]>dep[v]) swap(u,v); return max(ans,query(1,1,z,w[son[u]],w[v])); //uv之间统计 } void init() { scanf("%d",&n); es.clear(); for(int i=0;i<=n;i++) G[i].clear(); root=(n+1)/2; fa[root]=dep[root]=z=0; memset(siz,0,sizeof(siz)); memset(tree,0,sizeof(tree)); int u,v,c; for(int i=1;i<n;i++) { scanf("%d%d%d",&u,&v,&c); d[i][0]=u , d[i][1]=v , d[i][2]=c; adde(u,v,c) , adde(v,u,c); } dfs(root); build_tree(root,root); for(int i=1;i<n;i++) { if(dep[d[i][0]]>dep[d[i][1]]) swap(d[i][0],d[i][1]); update(1,1,z,w[d[i][1]],d[i][2]); } } void solve() { char s[20]; int u,v; while(scanf("%s",s)==1 && s[0]!='D') { scanf("%d%d",&u,&v); if(s[0]=='Q') printf("%d\n",find(u,v)); else update(1,1,z,w[d[u][1]],v); } } int main() { int T; scanf("%d",&T); while(T--) { init(); solve(); } return 0; }
相关文章推荐
- linq中AsEnumerable和AsQueryable的区别
- iOS应用开发中视图控件UIWindow的基本使用教程
- mongoose 文档(四) queries
- Flash Builder4.7安装
- 春节与UI
- 16 SequenceInputStream、PrintStream、Properties、递归、编码
- arduino 声波
- LeetCode60. Permutation Sequence
- HDU 2894 DeBruijin(欧拉回路)
- UITableView上的批量操作(系统方法)
- easyui-datagrid 的loader属性用法
- 导航控制器 UINavigationController
- Hibernate中inverse="true"的理解
- [翻译]The Neophyte's Guide to Scala Part 12: Type Classes
- 0206-UITableView上的批量操作(自定义)
- Arduino Nano + WIZ550io = 简易上网
- 百思学习笔记08-封装UIBarButtonItem的创建
- Android Wear Develope Guide 1
- UITableView UITableViewCell UITableViewController
- Unable to acquire PluginConverter service during generation