题目链接:http://poj.org/problem?id=1986

Farmer John's cows refused to run in his marathon since he chose a path much too long for their leisurely lifestyle. He therefore wants to find a path of a more reasonable length. The input to this problem consists of the same input as in "Navigation Nightmare",followed by a line containing a single integer K, followed by K "distance queries". Each distance query is a line of input containing two integers, giving the numbers of two farms between which FJ is interested in computing distance (measured in the length of the roads along the path between the two farms). Please answer FJ's distance queries as quickly as possible!

题目描述:已知n(n<=40000)个农场和一些农场之间的距离,给出很多组询问,在线询问每两个农场之间的距离。

算法分析:这道题运用LCA的在线和离线算法都可以。

离线LCA思路:以某一个农场为树根,用数组保存剩余每个农场到树根的距离为dist[u],那么农场u和v的距离=dist[u]+dist[v]-2*dist[q](q为LCA(u,v))。

我的做法虽然可以AC,但是很慢,有很大的优化空间:在两个节点不断向树根靠近的同时,把每向上走一层的路径上的权值(即农场之间的距离)加起来即为答案。我用离线的LCA代码运用在在线方法上,仔细想想在求每个节点的深度时就可以把离线思想中dist数组求出来了,更简单,速度更快。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<vector>
#define inf 0x7fffffff
using namespace std;
const int maxn=+;
const int max_log_maxn=; int n,m,root;
vector<pair<int,int> > G[maxn];
int father[max_log_maxn][maxn],d[maxn];
int sum[max_log_maxn][maxn]; void dfs(int u,int p,int depth)
{
father[][u]=p;
d[u]=depth;
int num=G[u].size();
for (int i= ;i<num ;i++)
{
int v=G[u][i].first;
int len=G[u][i].second;
if (v != p)
{
sum[][v]=len;
dfs(v,u,depth+);
}
}
} void init()
{
dfs(root,-,);
for (int k= ;k+<max_log_maxn ;k++)
{
for (int i= ;i<=n ;i++)
{
if (father[k][i]<)
{
father[k+][i]=-;
sum[k+][i]=;
}
else
{
father[k+][i]=father[k][father[k][i] ];
sum[k+][i]=sum[k][i]+sum[k][father[k][i] ];
}
}
}
} int LCA(int u,int v)
{
if (d[u]>d[v]) swap(u,v);
int Sum=;
for (int k= ;k<max_log_maxn ;k++)
{
if ((d[v]-d[u])>>k & )
{
Sum += sum[k][v];
v=father[k][v];
}
}
if (u==v) return Sum;
for (int k=max_log_maxn- ;k>= ;k--)
{
if (father[k][u] != father[k][v])
{
Sum += sum[k][u];
Sum += sum[k][v];
u=father[k][u];
v=father[k][v];
}
}
Sum += sum[][u];
Sum += sum[][v];
return Sum;
} int main()
{
while (scanf("%d%d",&n,&m)!=EOF)
{
int u,v,length;
char ch[];
for (int i= ;i<=n ;i++) G[i].clear();
for (int i= ;i<max_log_maxn ;i++)
{
for (int j= ;j<maxn ;j++)
sum[i][j]=;
}
for (int i= ;i<m ;i++)
{
scanf("%d%d%d%s",&u,&v,&length,ch);
G[u].push_back(make_pair(v,length));
G[v].push_back(make_pair(u,length));
}
root=;
init();
int k;
scanf("%d",&k);
for (int i= ;i<k ;i++)
{
scanf("%d%d",&u,&v);
printf("%d\n",LCA(u,v));
}
}
return ;
}

poj 1986 Distance Queries LCA的更多相关文章

  1. POJ.1986 Distance Queries ( LCA 倍增 )

    POJ.1986 Distance Queries ( LCA 倍增 ) 题意分析 给出一个N个点,M条边的信息(u,v,w),表示树上u-v有一条边,边权为w,接下来有k个询问,每个询问为(a,b) ...

  2. POJ 1986 Distance Queries LCA两点距离树

    标题来源:POJ 1986 Distance Queries 意甲冠军:给你一棵树 q第二次查询 每次你问两个点之间的距离 思路:对于2点 u v dis(u,v) = dis(root,u) + d ...

  3. POJ 1986 - Distance Queries - [LCA模板题][Tarjan-LCA算法]

    题目链接:http://poj.org/problem?id=1986 Description Farmer John's cows refused to run in his marathon si ...

  4. POJ 1986 Distance Queries(LCA Tarjan法)

    Distance Queries [题目链接]Distance Queries [题目类型]LCA Tarjan法 &题意: 输入n和m,表示n个点m条边,下面m行是边的信息,两端点和权,后面 ...

  5. POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 【USACO】距离咨询(最近公共祖先)

    POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 [USACO]距离咨询(最近公共祖先) Description F ...

  6. POJ 1986 Distance Queries 【输入YY && LCA(Tarjan离线)】

    任意门:http://poj.org/problem?id=1986 Distance Queries Time Limit: 2000MS   Memory Limit: 30000K Total ...

  7. POJ 1986 Distance Queries(Tarjan离线法求LCA)

    Distance Queries Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 12846   Accepted: 4552 ...

  8. poj 1986 Distance Queries(LCA)

    Description Farmer John's cows refused to run in his marathon since he chose a path much too long fo ...

  9. poj 1986 Distance Queries 带权lca 模版题

    Distance Queries   Description Farmer John's cows refused to run in his marathon since he chose a pa ...

随机推荐

  1. 瀑布流ListView

    前言 终于忙完了一段时间,现在前段时间写的一个瀑布流ListView到想法分享下,这个东西是扩展自Listview,当列表内容拉到最后后触发刷新操作,以便抓取更多到数据. 先贴下整个代码,先有个整体到 ...

  2. wordpress设置导航栏

    设置导航栏,首先你要设置你的导航分类.登陆后台---文章---分类目录,首先在这里输入你要写入导航的标题. 设置好后点击---外观---菜单这个地方就可以具体的设置导航的排序和下拉等二级

  3. iOS开发常用的宏

    #define SCREEN_WIDTH ([UIScreen mainScreen].bounds.size.width)#define SCREEN_HEIGHT ([UIScreen mainS ...

  4. python-抓取图片

    今天看到博客园一个文章,python抓取图片,也没看内容,心想自己也写一个抓取脚本试试看,一方面自己也在学习python,另一方面毕竟实际工作也经常会遇到这种需要临时写脚本的时候,突击锻炼还是好的嘛. ...

  5. C/C++ 内存管理 (《高质量C++》-- 整理笔记)

    内存管理是我们在编程时经常遇到的问题,而关于内存管理的问题往往会导致我们无从下手,这篇随笔是我阅读<高质量C++>第7章“内存管理”时一些总结. 1.内存分配方式 在C++中内存分为5个区 ...

  6. ListView的多布局中的小问题

    今天用到了ListView的多布局,我们需要额外重写两个方法 //返回多布局的个数 @Override public int getViewTypeCount() { return 3; } //用该 ...

  7. 2天驾驭DIV+CSS (基础篇)(转)

    这是去年看到的一片文章,感觉在我的学习中,有不少的影响.于是把它分享给想很快了解css的兄弟们. 基础篇[知识一] “DIV+CSS” 的叫法是不准确的[知识二] “DIV+CSS” 将你引入两大误区 ...

  8. C#中的索引

    索引代码示例:                 索引的使用示例:                       索引在经过编译器编译之后就相当于一个属性,进一步的说就是两个方法.       一个类允许 ...

  9. 使用 Bumblebee 控制 NVIDIA 双显卡

    简介 Nvidia的双显卡切换技术叫Optimus(擎天柱),可惜只能在win7.vista下实现.Linux下没有对应的技术,当然苹果也没有.这导致独立显卡一直在启用,显卡发热升温,风扇狂转,却没有 ...

  10. 设计移动App的十大技巧

    编写一款Android或iOS应用也许很容易,但是若想设计的成功却不是一件简单的事,用户界面对于一款移动应用的成功是至关重要的.也许你会说,为何界面那么糙的Flappy Bird可以大红大紫,可那毕竟 ...