【SPOJ QTREE】树链剖分模板
来源:互联网 发布:网络司法拍卖佣金 编辑:程序博客网 时间:2024/06/05 05:30
用线段树求解,这里注意由于求的是路径最大值,注意一下细节。
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAXN = 10010;#define lson (pos<<1)#define rson (pos<<1|1)const int INF = (1 << 30);int n;//--------------------------------------------------struct Edge{ int to,next;}edge[MAXN * 2];int head[MAXN],tot;int top[MAXN];int fa[MAXN];int deep[MAXN];int num[MAXN];int p[MAXN];int fp[MAXN];int son[MAXN];int pos;void init(){ tot = 0; memset(head,-1,sizeof(head)); pos = 1; memset(son,-1,sizeof(son));}void addedge(int u,int v){ edge[tot].to = v; edge[tot].next = head[u]; head[u] = tot ++;}void dfs1(int u,int pre,int d){ deep[u] = d; fa[u] = pre; num[u] = 1; for(int i = head[u]; i != -1; i = edge[i].next){ int v = edge[i].to; if(v != pre){ dfs1(v,u,d + 1); num[u] += num[v]; if(son[u] == -1 || num[v] > num[son[u]]) son[u] = v; //找重儿子 } }}void getpos(int u,int sp){ top[u] = sp; p[u] = pos++; //printf("%d %d\n",u,p[u]); fp[p[u]] = u; if(son[u] == -1) return; getpos(son[u],sp); for(int i = head[u]; i != -1; i = edge[i].next){ int v = edge[i].to; if(v != son[u] && v!= fa[u]) getpos(v,v); }}//----------------------------------------------int maxv[MAXN << 2]; //该一条边void build(){ memset(maxv,0,sizeof(maxv));}void pushup(int pos){ maxv[pos] = max(maxv[lson],maxv[rson]);}void update(int l,int r,int to,int value,int pos){ if(l == r){ maxv[pos] = value; return; } int mid = (l + r) >> 1; if(to <= mid) update(l,mid,to,value,lson); else update(mid + 1,r,to,value,rson); pushup(pos);}int query(int l,int r,int L,int R,int pos){ if(L <= l && r <= R) return maxv[pos]; int mid = (l + r) >> 1; int ret = - INF; if(L <= mid) ret = max(ret,query(l,mid,L,R,lson)); if(R > mid) ret = max(ret,query(mid + 1,r,L,R,rson)); return ret;}//-------------------------------------------------------int find(int u,int v){ int f1 = top[u],f2 = top[v]; int tmp = 0; while(f1 != f2){ if(deep[f1] < deep[f2]){ swap(f1,f2); swap(u,v); } tmp = max(tmp,query(1,pos,p[f1],p[u],1)); u = fa[f1]; f1 = top[u]; } if(u == v) return tmp; if(deep[u] > deep[v]) swap(u,v); return max(tmp,query(1,pos,p[son[u]],p[v],1));}//----------------------------------------------------------struct E{ int from,to,value;}e[MAXN];int main(){ int T; int u,v; scanf("%d",&T); while(T--){ scanf("%d",&n); init(); for(int i = 0; i < n - 1; i++){ scanf("%d%d%d",&e[i].from,&e[i].to,&e[i].value); addedge(e[i].from,e[i].to); addedge(e[i].to,e[i].from); } dfs1(1,0,0); getpos(1,1); build(); for(int i = 0; i < n - 1; i++){ if(deep[e[i].from] > deep[e[i].to]) swap(e[i].from,e[i].to); //这里是更新一条线段,不是一个点 update(1,pos,p[e[i].to],e[i].value,1); } char op[10]; while(scanf("%s",op) != EOF){ if(op[0] == 'D') break; scanf("%d%d",&u,&v); if(op[0] == 'Q'){ printf("%d\n",find(u,v)); } else{ update(1,pos,p[e[u - 1].to],v,1); } } if(T) puts(""); } return 0;}
0 0
- 【SPOJ QTREE】树链剖分模板
- SPOJ QTREE(树链剖分模板)
- 树链剖分模板+入门题 SPOJ - QTREE
- 树链剖分(SPOJ-QTREE)(模板)
- SPOJ - QTREE (树链剖分)
- SPOJ QTREE(树链剖分)
- 【高级数据结构】[SPOJ QTREE]树链剖分/动态树各一模板
- Spoj 375 QTREE(树链剖分)
- 树链剖分学习笔记 && SPOJ QTREE
- SPOJ QTREE
- SPOJ QTREE
- Spoj 375 Qtree 树链剖分 + 线段树 解法
- SPOJ 375 QTREE POJ 3237 TREE 树链剖分
- SPOJ QTREE(Query on a tree树链剖分)
- SPOJ QTREE Query on a tree --树链剖分
- [ SPOJ - QTREE]Query on a tree && 树链剖分
- SPOJ QTREE Query on a tree 树链剖分
- SPOJ QTREE Query on a tree 树链剖分
- Uva 10534
- Cocos2d-x问题纪录:removeChild和附有PhysicsBody的csb动画
- HDOJ 2044 一只小蜜蜂... 【递推】
- 834 组队【排序】
- 瀑布流在Angularjs中的使用
- 【SPOJ QTREE】树链剖分模板
- POJ3761 Bubble Sort
- UVA10288 Coupons
- C#中图片.BYTE[]和base64string的转换
- 6T-sram存储单元原理分析
- redis简介
- c++判断当前系统及编译器
- Haproxy解析
- 状态压缩讲解