链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586

【题意】

给出一个N 个和N-1条边的连通图,询问任意两点间的距离。N<=40000 。

【分析】

点太多了,用最短路算法来求超时。只够求一个点的单源最短路,而且不能用O(n2)的算法。正确的做法就是求出两点的最近公共祖先,利用点v到树的根节点距离dis[v]来换算。设要求的两点分别为u和v, 那么u和v的距离d=dis[u]+dis[v]-2*dis[LCA(u,v)] 。

现在还有一个问题就是输入是一个图,并不是一棵树,怎么有根节点?怎么确定父子关系?
     这个挺好办的,随便选一个点当根节点,从这个节点开始分层遍历,这样就有树的结构了。求dis数组我原先是用单源最短路来求的,不过仔细想下,因为原图就是一棵树,从根节点到任意点的路径是唯一的,于是就可以用递推的方式求的,在分层遍历中计算就好了。遍历递归的层数有点多,可能会爆栈。

这里我使用LCA转RMQ的方法来求的。

【代码】

 #pragma comment(linker, "/STACK:1024000000,1024000000") //扩栈
#include <stdio.h>
#include <string.h>
#include <vector>
#include <cmath>
using namespace std;
int n,m;
struct edge
{
int d,v,next;
edge(){}
edge(int _d,int _v,int _next)
{
d=_d;v=_v;next=_next;
}
}data[];
int map[];
int pool;
void addedge(int s,int e,int v)
{
int t=map[s];
data[pool++]=edge(e,v,t);
map[s]=pool-;
}
vector<int> f;
vector<int> b;
bool ifv[];
int pos[];
int dis[];
void dfs(int cur,int c)
{
if (cur< || cur>=n) return;
ifv[cur]=true;
pos[cur]=(int)f.size();
f.push_back(cur);
b.push_back(c);
int p=map[cur];
while (p!=-)
{
if (!ifv[data[p].d])
{
dis[data[p].d]=dis[cur]+data[p].v;
dfs(data[p].d,c+);
f.push_back(cur);
b.push_back(c);
}
p=data[p].next;
}
}
int rmq[][];
void makermq(int n,int bitn)
{
for (int i=; i<n; ++i)
rmq[i][]=b[i];
for (int j=; j<bitn; ++j)
for (int i=; i<n; ++i)
{
if (i+(<<(j-))>=n) break;
rmq[i][j]=min(rmq[i][j-],rmq[i+(<<(j-))][j-]);
}
}
int query(int s,int e)
{
int k=(int)((log(e-s+1.0)/log(2.0)));
return min(rmq[s][k],rmq[e-(<<k)+][k]);
}
int main()
{
int T;
scanf("%d",&T);
while (T--)
{
pool=;
f.clear();
b.clear();
memset(map,-,sizeof map);
memset(ifv,,sizeof ifv);
scanf("%d%d",&n,&m);
int s,e,v;
for (int i=;i<n-;++i)
{
scanf("%d%d%d",&s,&e,&v);
addedge(s-,e-,v);
addedge(e-,s-,v);
}
dis[]=;
dfs(,);
makermq(b.size(),(int)(log((double)b.size())/log(2.0)));
for (int i=;i<m;++i)
{
int u,v;
scanf("%d%d",&u,&v);
--u;--v;
int s=pos[u];
int e=pos[v];
if (s>e) swap(s,e);
int k=query(s,e);
k=f[k];
int ans=dis[u]+dis[v]-*dis[k];
printf("%d\n",ans);
}
}
}

HDU 2586 How far away? LCA 转化成RMQ的更多相关文章

  1. hdu 2586(最近公共祖先LCA)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 思路:在求解最近公共祖先的问题上,用到的是Tarjan的思想,从根结点开始形成一棵深搜树,非常好 ...

  2. HDU 2586 How far away(LCA+邻接表)

    How far away &题解: 和上篇是一样的题,这用的是lca方法做的, 不知道为什么,把数组开到80000 就a了 >_< 哈 我现在知道为什么了,因为我的rmq数组没有乘 ...

  3. HDU 2586 倍增法求lca

    How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  4. TTTTTTTTTTTTTTTTT HDU 2586 How far away LCA的离线算法 Tarjan

    链接: How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  5. LCA转换成RMQ

    LCA(Lowest Common Ancestor 最近公共祖先)定义如下:在一棵树中两个节点的LCA为这两个节点所有的公共祖先中深度最大的节点. 比如这棵树 结点5和6的LCA是2,12和7的LC ...

  6. HDU - 2586 How far away ?(LCA模板题)

    HDU - 2586 How far away ? Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & ...

  7. hdu 2586 How far away ?倍增LCA

    hdu 2586 How far away ?倍增LCA 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2586 思路: 针对询问次数多的时候,采取倍增 ...

  8. LCA(最近公共祖先)--tarjan离线算法 hdu 2586

    HDU 2586 How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/ ...

  9. hdu 2586(裸LCA)

    传送门 题意: 某村庄有n个小屋,n-1条道路连接着n个小屋(无环),求村庄A到村庄B的距离,要求是经过任一村庄不超过一次. 题解: 求出 lca = LCA(u,v) , 然后答案便是dist[u] ...

随机推荐

  1. Linux系统源码安装cloud-init

    参考:https://cloud.tencent.com/document/product/213/12587使用以下命令下载 cloud-init 源码包 官网下载地址:https://launch ...

  2. codebolocks 中文使用手册1.1

    Code::Blocks手册 使用篇 中文翻译版- 原手册下载:http://www.codeblocks.org/docs/manual_en.pdf 译者:JGood 译者言:工欲善其事,必先利其 ...

  3. poj1273 网络流入门题 dinic算法解决,可作模板使用

    Drainage Ditches Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 62078   Accepted: 2384 ...

  4. 【linxu】部署docker容器虚拟化平台

    实验所涉内容 Docker 概述 部署 docker 容器虚拟化平台 docker 平台基本使用方法 创建docker镜像和发布镜像方法 Container 容器端口映射 一 Docker 概述 Do ...

  5. JAVA中的使用Filter过滤器设置字符集

    Filter是什么? Filter不是一个Servlet,它可以叫做Servlet链,它可以用来改变一个request,修改一个response.它虽然不能产生一个response,但可以在一个req ...

  6. NBUT校赛 J Alex’s Foolish Function(分块+延迟标记)

    Problem J: Alex’s Foolish Function Time Limit: 8 Sec  Memory Limit: 128 MB Submit: 18  Solved: 2 Des ...

  7. [LOJ#6259]「CodePlus 2017 12 月赛」白金元首与独舞

    [LOJ#6259]「CodePlus 2017 12 月赛」白金元首与独舞 试题描述 到河北省 见斯大林 / 在月光下 你的背影 / 让我们一起跳舞吧 うそだよ~ 河北省怎么可能有 Stalin. ...

  8. vue嵌套路由与404重定向实现方法分析

    第一部分: vue嵌套路由 嵌套路由是什么? 嵌套路由就是在一个被路由过来的页面下可以继续使用路由,嵌套也就是路由中的路由的意思. 比如在vue中,我们如果不使用嵌套路由,那么只有一个<rout ...

  9. Bzoj2165 大楼

    Time Limit: 40 Sec  Memory Limit: 259 MBSubmit: 779  Solved: 285[Submit][Status][Discuss] Descriptio ...

  10. poj2728 最小比率生成树——01分数规划

    题目大意: 有n个村庄,村庄在不同坐标和海拔,现在要对所有村庄供水, 只要两个村庄之间有一条路即可,建造水管距离为坐标之间的欧几里德距离,费用为海拔之差, 现在要求方案使得费用与距离的比值最小,很显然 ...