HDU 2586 How far away (LCA模板题 树上点对间距离)
来源:互联网 发布:软件自动升级方案 编辑:程序博客网 时间:2024/06/03 20:11
题目链接
HDU2586
题目大意
给定一个n(n
分析
一看到题目最直观的感觉是一个最短路问题,但看数据规模,如果对于每一次询问都跑一遍最短路,肯定TLE,因此不能这么做。
由于,它是n个结点,n-1条边的图,因此是一棵树,所以要往树的算法上思考。树上两点之间的距离就是两个点到它们最近公共祖先的距离之和,于是问题转化为LCA问题。如果我们求出每一个结点到根节点的距离dis[i],则结点u到结点v的距离dist(u,v)=dis[u]+dis[v]-2*dis[LCA(u,v)].
dis[]可以在DFS的过程中求得。
代码
这里用基于RMQ的在线算法求LCA。
#include <iostream>#include <cstdio>#include <cstring>const int MAXN=40010;const int MAXM=80010;using namespace std;struct Edge{ int to,next,w;}e[MAXM];int vs[2*MAXN],depth[2*MAXN],id[MAXN],dis[MAXN],dmin[2*MAXN][17],cnt;int edgenum,n,m,head[MAXN];bool vis[MAXN];void Add_edge(int u,int v,int w){ e[++edgenum].to=v; e[edgenum].w=w; e[edgenum].next=head[u]; head[u]=edgenum;}void dfs(int u,int d)///u为当前访问到的结点,d为深度{ vis[u]=true; vs[++cnt]=u;///vs[]为深度优先访问树的完整路径(包含2*n-1个元素) cnt为时间戳 id[u]=cnt;///id[u]为u结点首次被访问时的时间戳 depth[cnt]=d;///depth[u]为u结点的深度 for (int t=head[u];t!=-1;t=e[t].next) { int v=e[t].to; int w=e[t].w; if (!vis[v]) { dis[v]=dis[u]+w; dfs(v,d+1); vs[++cnt]=u; depth[cnt]=d; } }}void RMQ_Init(int n)///dmin[]数组维护的是depth[]最小值对应下标{ for (int i=1;i<=n;i++) dmin[i][0]=i; for (int j=1;(1<<j)<=n;j++) for (int i=1;i+(1<<j)-1<=n;i++) { int a=dmin[i][j-1]; int b=dmin[i+(1<<(j-1))][j-1]; if (depth[a]<depth[b]) dmin[i][j]=a; else dmin[i][j]=b; }}int RMQ_min(int L,int R){ int k=0; while ((1<<(k+1))<=R-L+1) k++; int a=dmin[L][k]; int b=dmin[R-(1<<k)+1][k]; if (depth[a]<depth[b]) return a; else return b;}int LCA(int u,int v){ int x=id[u],y=id[v]; if (x>y) swap(x,y); int res=RMQ_min(x,y); return vs[res];}int main(){ int T,i,u,v,w,x,y; scanf("%d",&T); while (T--) { scanf("%d%d",&n,&m); edgenum=0;cnt=0; memset(head,-1,sizeof(head)); memset(id,0,sizeof(id)); memset(vs,0,sizeof(vs)); memset(dis,0,sizeof(dis)); memset(depth,0,sizeof(depth)); memset(vis,false,sizeof(vis)); for (i=1;i<n;i++) { scanf("%d%d%d",&u,&v,&w); Add_edge(u,v,w); Add_edge(v,u,w); } dfs(1,0); RMQ_Init(2*n-1); for (i=1;i<=m;i++) { scanf("%d%d",&x,&y); printf("%d\n",dis[x]+dis[y]-2*dis[LCA(x,y)]); } } return 0;}
阅读全文
0 0
- HDU 2586 How far away (LCA模板题 树上点对间距离)
- 【HDU】2586 How far away ? LCA求树上点对最近距离
- HDU 2586 How far away? LCA模板
- hdu 2586 How far away LCA在线RMQ(模板题)
- HDU 2586 How far away ?(LCA模板题)
- hdu 2586 How far away ? LCA 模板题
- HDU 2586 How far away LCA倍增模板
- HDU 2586 How far away ? (离线LCA Tarjan算法模板)
- HDU 2586 How far away?(lca模板)
- Hdu 2586 How far away ?【倍增LCA模板记录】
- LCA和RMQ练习,水题(LCA模板题):【hdu 2586】 How far away ?
- HDU2586 How far away ?(LCA模板题)
- HDU 2586 - How far away ? (LCA)
- hdu 2586 How far away ?(LCA)
- HDU--2586--How far away ?【LCA】
- HDU 2586 How far away ?(LCA)
- hdu 2586 How far away ?(LCA)
- hdu 2586 How far away ?(LCA)
- Mybatis 批量插入返回 主键ID
- Custom Key Managers in JSSE
- Android中Activity生命周期浅析
- SQLite学习手册(在线备份)
- android 抛弃Mvc ,初尝 Mvp 模式
- HDU 2586 How far away (LCA模板题 树上点对间距离)
- nginx配置静态资源,访问返回403
- Laravel5.4 不同环境下 env 文件设置
- 暑期ssh框架之struts2学习笔记三
- 漫聊android适配动态权限机制
- 2017 Multi-University Training Contest
- 迭代加深搜索--IDA*--uva11212 Editing a book
- c语言打印九九乘法表
- No qualifying bean of type 'com.yubai.el.ELConfig' available