POJ1986 Distance Queries(树链剖分LCA)
2016-03-05 17:08
337 查看
个人认为是树链剖分求lca的基本题目,当然其他方法也可以做。
大意:给出一棵n个节点的树,k(1<=k<=10000)个询问,每次询问树上两点的距离(每条道路后面输入的那个字母根本没什么卵用)
首先预处理每个节点i到根节点的距离,然后dis(i,j)=dis(i,root)+dis(j,root)−2∗dis(lca(i,j),root)dis(i,j)=dis(i,root)+dis(j,root)-2*dis(lca(i,j),root),时间复杂度为O(logn)O(logn)
大意:给出一棵n个节点的树,k(1<=k<=10000)个询问,每次询问树上两点的距离(每条道路后面输入的那个字母根本没什么卵用)
首先预处理每个节点i到根节点的距离,然后dis(i,j)=dis(i,root)+dis(j,root)−2∗dis(lca(i,j),root)dis(i,j)=dis(i,root)+dis(j,root)-2*dis(lca(i,j),root),时间复杂度为O(logn)O(logn)
#include<cstdio> #include<cstring> #include<iostream> #define MAXN 40010 using namespace std; struct tr { int v,w,next; }edge[MAXN*2]; int head[MAXN],cnt; void add_edge(int u,int v,int w) { edge[cnt].v = v; edge[cnt].w = w; edge[cnt].next = head[u]; head[u] = cnt++; } int n,m,q,x,y,z; int htp[MAXN],son[MAXN],sz[MAXN],dis[MAXN],fa[MAXN],dep[MAXN]; char ops[3]; void dfs1(int u,int f) { int maxnv = 0; for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].v; if(v == f) continue; dep[v] = dep[u]+1; dis[v] = dis[u]+edge[i].w; fa[v] = u; dfs1(v,u); sz[u] += sz[v]; if(sz[v] > sz[maxnv]) maxnv = v; } sz[u]++; son[u] = maxnv; } void dfs2(int u,int tp) { htp[u] = tp; if(son[u] == 0) return; dfs2(son[u],tp); for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].v; if(v == fa[u]||v == son[u]) continue; dfs2(v,v); } } int LCA(int u,int v) { while(1) { if(htp[u] == htp[v]) return dep[u]<=dep[v]?u:v; else if(dep[htp[u]] >= dep[htp[v]]) u = fa[htp[u]]; else v = fa[htp[v]]; } } int Dis(int u,int v) { return dis[u]+dis[v]-2*dis[LCA(u,v)]; } int main() { memset(head,-1,sizeof head); scanf("%d%d",&n,&m); for(int i = 1; i <= m; i++) { scanf("%d%d%d%s",&x,&y,&z,ops); add_edge(x,y,z); add_edge(y,x,z); } scanf("%d",&q); dfs1(1,-1); dfs2(1,1); for(int i = 1; i <= q; i++) { scanf("%d%d",&x,&y); printf("%d\n",Dis(x,y)); } }
相关文章推荐
- request.getScheme()+"://"+request.getServerName()+":"+request.getServerP
- 顺序表(Sequential List)
- android中SQLlite数据库中对应的SQL数据库的查询 query ,delete,insert
- 面试常客Handler详细解析(Handler与Looper、MessageQueue的关系)(二)
- UITextfield属性(初级篇)
- 由SequenceFile.Writer(key,value)谈toString()方法
- UESTC--1251--谕神的密码(贪心)
- UESTC--1251--谕神的密码(贪心)
- 需要优化软件UI,so 沉寂许久之后开始学习界面的课程,把文档直接贴过来自己试着翻译
- 《腾讯网UED体验设计之旅》读后感
- self表示的是当前类开辟内存的对象(文档里写的是当前的消息接受者 Return Value: The receiver.)
- hdoj-1058(优先队列)---priority_queue====丑数
- HDU 4126 Genghis Khan the Conqueror(最小生成树)
- iOS之UIScrollView常用属性和用法总结
- DataBase -- Employees Earning More Than Their Managers My Submissions Question
- kidd风的IOS日志之UICollectionView之介绍使用篇
- 系统默认的刷新方法(UIRefreshControl)
- N1:Stack Queue DFS BFS
- 让UITableViewCell的分隔线宽度等于屏幕的宽度
- UESTC 758 P酱的冒险旅途