POJ 1986 - Distance Queries - [LCA模板题][Tarjan-LCA算法]
题目链接:http://poj.org/problem?id=1986
Description
Input
* Line 2+M: A single integer, K. 1 <= K <= 10,000
* Lines 3+M..2+M+K: Each line corresponds to a distance query and contains the indices of two farms.
Output
Sample Input
7 6
1 6 13 E
6 3 9 E
3 5 7 S
4 1 3 N
2 4 20 W
4 7 2 S
3
1 6
1 4
2 6
Sample Output
13
3
36
Hint
题意:
输入第1~M+1行,与POJ 1984相同,代表了农场地图。
然后再一行有一个整数K代表询问数,
再然后有K个询问u和v之间最短距离。
题解:
本题的输入确定了农场地图是一棵树,并且本题不需要知道农场之间的位置关系,所以不需要记录东西南北。
树上两点间的最短距离,有两种情况:
①u是v的祖先,则dist(u,v) = dist(root,v) - dist(root,u)
②u不是v的祖先,那么从u到v必然要经过LCA(u,v),显然就是最短路径,则dist(u,v) = dist(root,u) - dist(root,LCA(u,v)) + dist(root,v) - dist(root,LCA(u,v))
不难发现,第①种情况下,dist(root,LCA(u,v)) = dist(root,u),那么①和②就可以统一为:dist(u,v) = dist(root,u) + dist(root,v) - 2 * dist(root,LCA(u,v))
所以我们只要计算出每个节点和树根的距离,求出所有查询(u,v)的LCA(u,v),就能得到dist(u,v)。
AC代码:
#include<cstdio>
#include<vector>
using namespace std; const int maxn=+; //节点数
const int maxm=+; //边数
const int maxq=+; //查询数 int par[maxn];
int find(int x){return (par[x]==x)?x:(par[x]=find(par[x]));} struct Edge{
int u,v,w;
Edge(int u=,int v=,int w=){this->u=u,this->v=v,this->w=w;}
};
vector<Edge> E;
vector<int> Ge[maxn];
void addedge(int u,int v,int w)
{
E.push_back(Edge(u,v,w));
Ge[u].push_back(E.size()-);
} struct Query{
int u,v;
int lca;
Query(int u=,int v=,int lca=){this->u=u,this->v=v,this->lca=lca;}
};
vector<Query> Q;
vector<int> Gq[maxn];
void addquery(int u,int v)
{
Q.push_back(Query(u,v));
Gq[u].push_back(Q.size()-);
} bool vis[maxn];
int dist[maxn];
void LCA(int u,int d)
{
par[u]=u; //建立以u为代表元素的集合
vis[u]=;
dist[u]=d;
for(int i=;i<Ge[u].size();i++)
{
Edge &e=E[Ge[u][i]]; int v=e.v;
if(!vis[v])
{
LCA(v,d+e.w);
par[v]=u; //将v的集合并入u的集合
}
}
for(int i=;i<Gq[u].size();i++)
{
Query &q=Q[Gq[u][i]]; int v=q.v;
if(vis[v])
{
q.lca=find(v);
Q[Gq[u][i]^].lca=q.lca;
}
}
} int m,n,k;
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
int u,v,w; char d[];
scanf("%d%d%d%s",&u,&v,&w,d);
addedge(u,v,w);
addedge(v,u,w);
} scanf("%d",&k);
for(int i=;i<=k;i++)
{
int u,v;
scanf("%d%d",&u,&v);
addquery(u,v);
addquery(v,u);
} LCA(,); for(int i=;i<=k;i++)
{
printf("%d\n",dist[Q[(i-)*].u]+dist[Q[(i-)*].v]-*dist[Q[(i-)*].lca]);
}
}
POJ 1986 - Distance Queries - [LCA模板题][Tarjan-LCA算法]的更多相关文章
- POJ.1986 Distance Queries ( LCA 倍增 )
POJ.1986 Distance Queries ( LCA 倍增 ) 题意分析 给出一个N个点,M条边的信息(u,v,w),表示树上u-v有一条边,边权为w,接下来有k个询问,每个询问为(a,b) ...
- POJ 1986 Distance Queries LCA两点距离树
标题来源:POJ 1986 Distance Queries 意甲冠军:给你一棵树 q第二次查询 每次你问两个点之间的距离 思路:对于2点 u v dis(u,v) = dis(root,u) + d ...
- POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 【USACO】距离咨询(最近公共祖先)
POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 [USACO]距离咨询(最近公共祖先) Description F ...
- POJ 1986 Distance Queries 【输入YY && LCA(Tarjan离线)】
任意门:http://poj.org/problem?id=1986 Distance Queries Time Limit: 2000MS Memory Limit: 30000K Total ...
- POJ 1986 Distance Queries(LCA Tarjan法)
Distance Queries [题目链接]Distance Queries [题目类型]LCA Tarjan法 &题意: 输入n和m,表示n个点m条边,下面m行是边的信息,两端点和权,后面 ...
- POJ 1470 Closest Common Ancestors (模板题)(Tarjan离线)【LCA】
<题目链接> 题目大意:给你一棵树,然后进行q次询问,然后要你统计这q次询问中指定的两个节点最近公共祖先出现的次数. 解题分析:LCA模板题,下面用的是离线Tarjan来解决.并且为了代码 ...
- POJ 1330 Nearest Common Ancestors (模板题)【LCA】
<题目链接> 题目大意: 给出一棵树,问任意两个点的最近公共祖先的编号. 解题分析:LCA模板题,下面用的是树上倍增求解. #include <iostream> #inclu ...
- POJ 1986 Distance Queries(Tarjan离线法求LCA)
Distance Queries Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 12846 Accepted: 4552 ...
- poj 1986 Distance Queries 带权lca 模版题
Distance Queries Description Farmer John's cows refused to run in his marathon since he chose a pa ...
随机推荐
- Jackson Gson Json.simple 比较
为公司做了小任务,需要用到Java Json库,Json库我几个月之前就用过,不过那时候是跟着项目来的,延续了项目的使用习惯直接用了jackson Json,而这次我觉得好好比较一下几个常见的Json ...
- 图解Python深拷贝和浅拷贝
Python中,对象的赋值,拷贝(深/浅拷贝)之间是有差异的,如果使用的时候不注意,就可能产生意外的结果. 下面本文就通过简单的例子介绍一下这些概念之间的差别. 对象赋值 直接看一段代码: will ...
- Python 爬虫系列:糗事百科最热段子
1.获取糗事百科url http://www.qiushibaike.com/hot/page/2/ 末尾2指第2页 2.分析页面,找到段子部分的位置, 需要一点CSS和HTML的知识 3.编写 ...
- error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version
更新的软件可以解决 TortoiseGit-preview-2.5.7.0-20180127-b2d00f8-64bit.msi和Git-2.16.2-64-bit.exe. 链接地址为: https ...
- Linux下chkconfig命令详解转载
chkconfig命令主要用来更新(启动或停止)和查询系统服务的运行级信息.谨记chkconfig不是立即自动禁止或激活一个服务,它只是简单的改变了符号连接. 使用语法:chkconfig [--ad ...
- jQuery ajax中serialize()方法增加其他参数
表单提交 使用jQuery.ajax()进行表单提交时,需要传递参数,最直接的方法便是使用Form的serializa()将表单序列化,前提只是将Form表单中的name属性与数据库的字段名保持一致便 ...
- 【LeetCode OJ】Longest Palindromic Substring
题目链接:https://leetcode.com/problems/longest-palindromic-substring/ 题目:Given a string S, find the long ...
- ubuntu下升级特定软件与查看软件版本信息
ubuntu 升级软件: sudo apt-get update 更新源 sudo apt-get upgrade 更新已安装的包 sudo apt-get dist-upgrade 升级系统 ubu ...
- Qt——布局管理器
教程地址 运行截图: 代码: #include "mainwindow.h" #include <QApplication> #include <QHBoxLay ...
- WP8.1学习系列(第十六章)——交互UX之命令模式
命令模式 在本文中 命令类型 命令放置 相关主题 你可以在应用商店应用的几个曲面中放置命令和控件,包括应用画布.弹出窗口.对话框和应用栏.在正确的时间选择合适的曲面可能就是易于使用的应用和很难使用 ...