[UESTC 1437]谭松松的旅游计划
来源:互联网 发布:猿课软件 编辑:程序博客网 时间:2024/04/30 23:04
谭松松是一个爱旅游的人,他非常的热爱旅游,即便身体被掏空也要坚持旅游。喵蛤王国由N个城市组成,由N-1条道路连通,每条道路长度为ci,使得任意两座城市都能相互到达。谭松松有M个旅游计划,每个旅游计划有一个起点ai,一个终点bi,所以谭松松想知道,对于每个旅游计划,从起点到终点的最短路长度为多少?
输入:
第一行两个整数N(2≤N≤100000),M(1≤M≤100000),表示城市个数,谭松松的旅游计划个数。
接下来N-1行,每行三个整数li,ri,ci(1≤ci≤10000),表示li号城市和ri号城市之间有一条长度为ci的道路。
接下来M行,每行两个整数ai,bi表示旅游计划的起点和终点。
输出
输出M行,表示每个旅游计划的最短距离。
样例输入
7 6
1 2 5
1 3 4
3 7 7
2 4 4
2 5 3
5 6 2
1 2
4 7
6 3
3 2
5 4
7 6
样例输出
5
20
14
9
7
21
题解:由题意可知,所有的点在一颗树上,那么我们只需要找到a,b的最近公共祖先LCA(a,b),a,b之间的距离就是dis[a]+dis[b]-dis[LCA(a,b)]*2 (dis[i]表示从树的根节点到i点的距离),在线求LCA我们一般使用倍增算法,单次询问复杂度为O(logn)
#include<iostream>#include<cstdio>#include<cstdlib>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<vector>#define LiangJiaJun mainusing namespace std;int n,m,ne=1,h[100004],deep[100004],dis[100004];bool vis[100004];int fa[100004][24];queue<int>q;struct edge{ int to,next,w;}e[900004];void insert(int u,int v,int w){ e[++ne].to=v;e[ne].next=h[u];e[ne].w=w;h[u]=ne;}void RESET(){ memset(fa,0,sizeof(fa)); ne=1;memset(h,0,sizeof(h)); memset(vis,0,sizeof(vis)); memset(dis,127/3,sizeof(dis)); memset(deep,0,sizeof(deep));}void BFS(int st){ q.push(st); dis[st]=0; deep[st]=1; while(!q.empty()){ int x=q.front();q.pop(); for(int i=h[x];i;i=e[i].next){ if(dis[e[i].to] > dis[x] + e[i].w){ dis[e[i].to] = dis[x] + e[i].w; q.push(e[i].to); } } }}void DFS(int x){ vis[x] = 1; for(int i=1;i<=20;i++)fa[x][i] = fa[fa[x][i-1]][i-1]; for(int i=h[x];i;i=e[i].next){ if(vis[e[i].to])continue; fa[e[i].to][0]=x; deep[e[i].to]=deep[x]+1; DFS(e[i].to); }}int LCA(int u,int v){ if(deep[u]<deep[v])swap(u,v); int dva=deep[u]-deep[v]; for(int i=0;i<=20;i++) if(dva&(1<<i))u=fa[u][i]; for(int i=20;i>=0;i--){ if(fa[u][i]!=fa[v][i]){ u=fa[u][i]; v=fa[v][i]; } } if(u==v)return u; return fa[u][0];}void work(){ RESET(); for(int i=1;i<n;i++){ int u,v,w; scanf("%d%d%d",&u,&v,&w); insert(u,v,w);insert(v,u,w); } BFS(1); DFS(1); while(m--){ int a,b,t; scanf("%d%d",&a,&b); t=LCA(a,b); printf("%d\n",dis[a]+dis[b]-dis[t]*2); }}int LiangJiaJun(){ while(scanf("%d%d",&n,&m)!=EOF)work(); return 0;}
0 0
- [UESTC 1437]谭松松的旅游计划
- CSU OJ:1427 谭松松的旅游计划(LCA)
- 谭松松的旅游计划 【LCA 求最短路】
- X的旅游计划
- 我的端午旅游计划!
- 计划旅游,合理旅游
- 旅游计划
- 旅游计划
- vijos P1966 夜夜的旅游计划
- Vijos 1966 夜夜的旅游计划 高斯消元
- 松松松松
- 巴厘岛旅游计划
- 四川雅安旅游计划
- [BZOJ2117][2010国家集训队]Crash的旅游计划
- 卢松松的博客导航网
- 旅游计划(树形dp)
- 用xmind写旅游计划
- 馅饼又掉下来,让完美的baichi的旅游计划顺利进行
- 多线程总结:
- 剑指Offer笔记<JAVA版>(二)
- 父类引向子类对象
- cache和命中率的问题
- try catch finally
- [UESTC 1437]谭松松的旅游计划
- linux服务器在线下载JDK
- 最小生成树-Kruskal
- 不允许拷贝构造函数传值参数,而必须是传引用或者常量引用
- linux系统(ubuntu)如何查看ip地址
- Content-Type
- HTML初体验(一)
- linux环境下Python的安装过程
- 匈牙利算法