题目链接: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. 洛谷-三连击(升级版)-BOSS战-入门综合练习1

    题目描述 Description 将1,2,…,9共9个数分成三组,分别组成三个三位数,且使这三个三位数构成A:B:C的比例,试求出所有满足条件的三个三位数,若无解,输出“No!!!”.  输入输出格 ...

  2. REST认识

    大家对REST的认识? 谈到REST大家的第一印象就是通过http协议的GET,POST,DELETE,PUT方法实现对url资源的CRUD(创建.读取.更新和删除)操作.比如http://www.a ...

  3. UITextField的属性设置

    1.背景颜色 field.backgoundColor = [UIColor redColor]; 2.设置field文字 field.text = @"输入文字"; 3.设置fi ...

  4. 9.创建一个三角形类,成员变量三边,方法求周长,创建类主类A来测试它。

    package com.hanqi.test; public class Triangle { private double a,b,c; public Triangle(double d,doubl ...

  5. mysql备份并自动压缩命令

    #! /bin/bash mysqldump -uroot -p'password' databasename | gzip > /home/backup/database_`date +%Y% ...

  6. iOS UITextView 根据输入text自适应高度

    转载自:http://www.cnblogs.com/tmf-4838/p/5380495.html #import "ViewController.h" @interface V ...

  7. (转载)测试工具monkey

    转自http://www.418log.org/post-32.html 1)进入shell 在桌面点开始--运行 输入cmd 点确定 或打开 cmd.exe 进入sdk tools目录如: 1 C: ...

  8. Kmeans聚类算法

    K-means也是聚类算法中最简单的一种了,但是里面包含的思想却是不一般.最早我使用并实现这个算法是在学习韩爷爷那本数据挖掘的书中,那本书比较注重应用.看了Andrew Ng的这个讲义后才有些明白K- ...

  9. java代码如何读取properties文件

    我们在开发工程中,有时候需要在Java代码中定义一些在部署生产环境时容易改变的变量,还需要我们单独放在一个外部属性文件中,方便我们将来修改.这里列出了两种比较方便的方式. 一.在Spring配置文件中 ...

  10. MFC连接Access讲解(3合1) .

    方法一: 1.首先,要用#import语句来引用支持ADO的组件类型库(*.tlb),其中类型库可以作为可执行程序(DLL.EXE等)的一部分被定位在其自身程序中的附属资源里,如:被定位在msado1 ...