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

题目大意:在一个无向树上,求一条链权和。

解题思路

0

|

1

/   \

2      3

设dist[i]为i到根0的链和,求法(Dfs过程中dist[v]=dist[u]+e[i].w)

对于树中任意两点形成的链,可以通过LCA最近公共祖先剖分。

比如2->3,就可以经过LCA点1:  2->1->3

链和=dist[u]+dist[v]-2*dist[LCA[u,v]]

(0-1-2)+(0-1-3)-2*(0-1)=(2-1-3),有点容斥原理的味道。

LCA比较快的是Tarjan离线法,把全部query也做成一个无向树,离线处理。

过程分为两个stage,stage 1对连接树处理,stage 2对query树处理。

两个stage可以颠倒。正写法 倒写法。在Tarjan(u)中,并查集find(v),可以获得LCA。

LCA存储比较头疼,由于LCA是双向共享的。可以建个ancestor数组,索引是查询序号。

也可以直接存在query树的链式前向星中。

本题双向建一个无向树,任意选择一个起点作为root做LCA都可以。

#include "cstdio"
#include "cstring"
#define maxn 40005
#define maxm 205
int head[maxn],qhead[maxn],dist[maxn],tot1,tot2,f[maxn],vis[maxn],ancestor[maxn];
struct Edge
{
int to,next,w;
}e[maxn*];
struct Query
{
int from,to,next,idx;
}q[maxn*];
void addedge(int u,int v,int w)
{
e[tot1].to=v;
e[tot1].w=w;
e[tot1].next=head[u];
head[u]=tot1++;
}
void addquery(int u,int v,int idx)
{
q[tot2].from=u;
q[tot2].to=v;
q[tot2].next=qhead[u];
q[tot2].idx=idx;
qhead[u]=tot2++;
}
int find(int x) {return x!=f[x]?f[x]=find(f[x]):x;}
void Union(int u,int v)
{
u=find(u),v=find(v);
if(u!=v) f[v]=u;
}
void LCA(int u)
{
vis[u]=true;
f[u]=u;
for(int i=head[u];i!=-;i=e[i].next)
{
int v=e[i].to,w=e[i].w;
if(!vis[v])
{
dist[v]=dist[u]+w;
LCA(v);
Union(u,v);
}
}
for(int i=qhead[u];i!=-;i=q[i].next)
{
int v=q[i].to;
if(vis[v]) ancestor[q[i].idx]=find(v);
//or storage e[i].lca=e[i^1].lca=find(v)
}
}
int main()
{
//freopen("in.txt","r",stdin);
int T,n,m,u,v,c;
scanf("%d",&T);
while(T--)
{
tot1=tot2=;
memset(head,-,sizeof(head));
memset(qhead,-,sizeof(qhead));
memset(vis,,sizeof(vis));
dist[]=;
scanf("%d%d",&n,&m);
for(int i=;i<n-;i++)
{
scanf("%d%d%d",&u,&v,&c);
addedge(u,v,c);
addedge(v,u,c);
}
for(int i=;i<m;i++)
{
scanf("%d%d",&u,&v);
addquery(u,v,i);
addquery(v,u,i);
}
LCA();
for(int i=;i<tot2;i=i+)
{
int u=q[i].from,v=q[i].to,idx=q[i].idx;
printf("%d\n",dist[u]+dist[v]-*dist[ancestor[idx]]);
}
}
}

HDU 2586 (LCA模板题)的更多相关文章

  1. [hdu 2586]lca模板题(在线+离线两种版本)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 在线版本: 在线方法的思路很简单,就是倍增.一遍dfs得到每个节点的父亲,以及每个点的深度.然后 ...

  2. hdu - 2586 (LCA板子题)

    传送门 (这次的英文题面要比上一个容易看多了) (英语蒟蒻的卑微) 又是一个很裸的LCA题 (显然,这次不太容易打暴力咧) (但听说还是有大佬用dfs直接a掉了) 正好 趁这个机会复习一下LCA 这里 ...

  3. hdu 2586 How far away?(LCA模板题+离线tarjan算法)

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

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

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

  5. HDU 2586——How far away ?——————【LCA模板题】

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

  6. HDU 2138 Miller-Rabin 模板题

    求素数个数. /** @Date : 2017-09-18 23:05:15 * @FileName: HDU 2138 miller-rabin 模板.cpp * @Platform: Window ...

  7. HDU 2586 How far away ?【LCA模板题】

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意:给你N个点,M次询问.1~N-1行输入点与点之间的权值,之后M行输入两个点(a,b)之间的最 ...

  8. HDU 2586 How far away ? 离线lca模板题

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

  9. HDU 2586 ( LCA/tarjan算法模板)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意:n个村庄构成一棵无根树,q次询问,求任意两个村庄之间的最短距离 思路:求出两个村庄的LCA,d ...

随机推荐

  1. Thinkphp3.2中的模板继承

    1:模板继承:   是3.1.2版本添加的一项更加灵活的模板布局方式,模板继承不同于模板布局,甚至来说,应该在模板布局的上层.模板继承其实并不难理解,就好比 类的继承一样,模板也可以定义一个基础模板( ...

  2. 电脑没有关机可能出现发博文dns异常(write)

    现在是把装系统的技巧基本掌握,其实弄了这么多次还是有一个突破点,就是安装系统win7选择cd的iso是要ide模式.

  3. (转)ORA-12519: TNS:no appropriate service handler found 的问题处理。

    很多时候出现:ORA-12519: TNS:no appropriate service handler found 都是由于当前的连接数已经超出他能够处理的最大值了. 处理方法如下:摘自网上. se ...

  4. Java 解析XML的几种方法

    XML现在已经成为一种通用的数据交换格式,它的平台无关性,语言无关性,系统无关性,给数据集成与交互带来了极大的方便. XML在不同的语言里解析方式都是一样的,只不过实现的语法不同而已. 基本的解析方式 ...

  5. Android之Picasso --zz

    简介: Picasso是Square公司开源的一个Android图形缓存库.可以实现图片下载和缓存功能. 特点: 1.加载载网络或本地图片并自动缓存处理: 2.链式调用: 3.图形转换操作,如变换大小 ...

  6. java中常用的工具类(二)

    下面继续分享java中常用的一些工具类,希望给大家带来帮助! 1.FtpUtil           Java   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...

  7. 跟着鸟哥学Linux系列笔记1

    跟着鸟哥学Linux系列笔记0-扫盲之概念 跟着鸟哥学Linux系列笔记0-如何解决问题 装完linux之后,接下来一步就是进行相关命令的学习了 第五章:首次登录与在线求助man page 1. X ...

  8. 汇编学习(四)——算术运算程序

    (一)跳转指令 一.无条件跳转指令(不管标志寄存器,执行到这句直接跳转) 1.段内直接跳转指令 (1)指令格式: JMP SHORT short_label; IP<--IP+DB,即代码直接跳 ...

  9. cocos2dx游戏开发——微信打飞机学习笔记(三)——WelcomeScene的搭建

    一.场景与层的关系: cocos2dx的框架可以说主要由导演,场景,层,精灵来构成: 1.其中导演,意如其名,就是操控整个游戏的一个单例,管理着整个游戏. 2.场景就像电影的一幕剧情,所以说,懂得如何 ...

  10. OpenGL大作业

    GLfloat light0_position[] = { 15.0,15.0,15.0,10.0 };//定义光源位置 103glLightfv(GL_LIGHT0, GL_POSITION, li ...