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

最近公共祖先问题~~LAC离散算法

题目大意:一个村子里有n个房子,这n个房子用n-1条路连接起来,接下了有m次询问,每次询问两个房子a,b之间的距离是多少。

很明显的最近公共祖先问题,先建一棵树,然后求出每一点i到树根的距离dis[i],然后每次询问a,b之间的距离=dis[a]+dis[b]-2*dis[LCA(a,b)];

LCA(a,b)即是a,b的最近公共祖先。。

关于最近公共祖先,给大家推荐一个学长的博客http://www.cnblogs.com/ylfdrib/archive/2010/11/03/1867901.html,里面讲的很不错!!

 # include<stdio.h>
# include<string.h>
# define N
# define M
struct node{
int from,to,next,val;
}edge[*N];
struct node1{
int from,to,next,num;
}edge1[*M];
int tol,head[N],head1[N],tol1,father[N],dis[N],LCA[M],n,m;
bool visit[N];
void add(int a,int b,int c)
{
edge[tol].from=a;edge[tol].to=b;edge[tol].next=head[a];edge[tol].val=c;head[a]=tol++;
}
void add1(int a,int b,int c)
{
edge1[tol1].from=a;edge1[tol1].to=b;edge1[tol1].next=head1[a];edge1[tol1].num=c;head1[a]=tol1++;
}
int find(int x)
{
if(x!=father[x])
father[x]=find(father[x]);
return father[x];
}
void tarjan(int u)
{
int j,v;
visit[u]=;
father[u]=u;
//////////////////
for(j=head1[u];j!=-;j=edge1[j].next)
{
v=edge1[j].to;
if(visit[v]) LCA[edge1[j].num]=find(v);
}
//////////////////
for(j=head[u];j!=-;j=edge[j].next)
{
v=edge[j].to;
if(!visit[v])
{
dis[v]=dis[u]+edge[j].val;
tarjan(v);
father[v]=u;
}
}
}
int main()
{
int i,ncase,a,b,c;
scanf("%d",&ncase);
while(ncase--)
{
scanf("%d%d",&n,&m);
tol=;
memset(head,-,sizeof(head));
for(i=;i<n;i++)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
}
memset(visit,,sizeof(visit));
tol1=;
memset(head1,-,sizeof(head1));
for(i=;i<=m;i++)
{
scanf("%d%d",&a,&b);
add1(a,b,i);
add1(b,a,i);
}
///LCA是一种离线算法,所以刚开始需要把所有的询问都输入,然后用邻接表进行存储,i表示第i次询问
dis[]=;
tarjan();
for(i=;i<tol1;i+=)
{
a=edge1[i].from;
b=edge1[i].to;
c=edge1[i].num;
printf("%d\n",dis[a]+dis[b]-*dis[LCA[c]]);
}
}
return ;
}

**************************

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std; const int NN=; int n,m;
vector<pair<int,int> > edge[NN],qe[NN];
vector<int> q1,q2; int p[NN];
int find(int x)
{
if (p[x]!=x) p[x]=find(p[x]);
return p[x];
} int sum=,ans[NN],dis[NN];
bool vis[NN]={};
void lca(int u,int fa)
{
p[u]=u;
for (int i=; i<edge[u].size(); i++)
{
int v=edge[u][i].first;
if (v==fa) continue;
dis[v]=dis[u]+edge[u][i].second;
lca(v,u);
p[v]=u;
}
vis[u]=true;
if (sum==m) return;
for (int i=; i<qe[u].size(); i++)
{
int v=qe[u][i].first;
if (vis[v])
ans[qe[u][i].second]=dis[u]+dis[v]-*dis[find(v)];
}
} int main()
{
int u,v,w; int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for (int i=; i<=n; i++)
{
edge[i].clear();
}
for (int i=; i<n; i++)
{
scanf("%d%d%d",&u,&v,&w);
edge[u].push_back(make_pair(v,w));
edge[v].push_back(make_pair(u,w));
} for (int i=; i<m; i++)
{
scanf("%d%d",&u,&v);
qe[u].push_back(make_pair(v,i));
qe[v].push_back(make_pair(u,i));
ans[i]=;
}
dis[]=;
lca(,);
for (int i=; i<m; i++) printf("%d\n",ans[i]);
}
return ;
}

hdu - 2586 How far away ?(最短路共同祖先问题)的更多相关文章

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

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

  2. hdu 2586 How far away ?倍增LCA

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

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

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

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

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

  5. HDU 2586 How far away? LCA 转化成RMQ

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 [题意] 给出一个N 个和N-1条边的连通图,询问任意两点间的距离.N<=40000 . [分 ...

  6. HDU 2586

    http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意:求最近祖先节点的权值和 思路:LCA Tarjan算法 #include <stdio.h&g ...

  7. hdu 2586 How far away

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

  8. HDU 2586 (LCA模板题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2586 题目大意:在一个无向树上,求一条链权和. 解题思路: 0 | 1 /   \ 2      3 ...

  9. HDU 5637 Transform 单源最短路

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5637 题意: http://bestcoder.hdu.edu.cn/contests/contes ...

随机推荐

  1. OC之消息调用过程

    Bird * aBird = [[Bird alloc] init]; [aBird fly]; 中对 fly 的调用,编译器通过插入一些代码,将之转换为对方法具体实现 IMP 的调用,这个 IMP ...

  2. tomcat源码分析(二)启动过程

    在Catalina的load方法中,首先初始化Server组件. // Start the new server if (server instanceof Lifecycle) { try { se ...

  3. AIX 永久修改环境变量

    转自:http://blog.sina.com.cn/s/blog_5e3122450100stk5.html 方法一:PATH=$PATH:/usr/XX        export PATH重启一 ...

  4. hdu 5584 gcd/lcm/数学公式

    input T 1<=T<=1000 x y output 有多少个起点可以走n(n>=0)步走到(x,y),只能从(x,y)走到(x,y+lcm(x,y))/(x+lcm(x,y) ...

  5. C++侵入式链表

    C++标准模板库中的list是非侵入式的链表,当我们通过对象来删除容器中的对象时,需要从头到尾查找一次得到iterator,最后通过iterator来删除对象.这样删除容器中的对象时比较缓慢,所以就实 ...

  6. vbs 读取txt是读取特定的行

    读取第三行的内容:Set fso = CreateObject("scripting.filesystemobject")path="A.TXT文件的路径"Se ...

  7. Varnish && Varnish Cache

    1 1 1 Varnish https://www.varnish-cache.org/intro/index.html#intro Introduction to Varnish The basic ...

  8. @Autowired 和 @Resource

    转自:Spring中@Autowired注解.@Resource注解的区别 Spring不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定义的注解,它们分别是@Resourc ...

  9. gets()

    C: #include <stdio.h>    //这个头文件包含gets()函数,这个函数在ISO/IEC 9899 2011(C11)标准中被移除 int main(void) { ...

  10. 新建web project不自动生成web.xml解决方案

    一步一步建立Web Project ,第3步会有 “Generate Web.xml deployment descriptor”,默认没勾选,勾上就行了