POJ 1986:Distance Queries
Distance Queries
Time Limit: 2000MS | Memory Limit: 30000K | |
Total Submissions: 18139 | Accepted: 6248 | |
Case Time Limit: 1000MS |
Description
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!
Input
* Lines 1..1+M: Same format as "Navigation Nightmare"
* 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
* Lines 1..K: For each distance query, output on a single line an integer giving the appropriate distance.
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
Farms 2 and 6 are 20+3+13=36 apart.
题意
n个点,m条边,每两个相连的点有一个距离,对于每次询问,求出u,v的距离
思路
因为题中给出的图是一个树(Navigation Nightmare题目链接:http://poj.org/problem?id=1984)
对于树上的两点距离,我们有:dis(u,v)=dis(u,root)+dis(v,toot)-2*dis(lca(u,v),root)
预处理出来每个点到根节点的距离,在查询的时候求出u,v两点的lca,然后利用上述公式计算即可
因为是一棵树,所以可以以任意一个节点作为根节点
代码
- 1 #include <algorithm>
- 2 #include <iostream>
- 3 #include <string.h>
- 4 #define ll long long
- 5 #define ull unsigned long long
- 6 #define ms(a,b) memset(a,b,sizeof(a))
- 7 const int inf=0x3f3f3f3f;
- 8 const ll INF=0x3f3f3f3f3f3f3f3f;
- 9 const int maxn=2e5+10;
- 10 const int mod=1e9+7;
- 11 const int maxm=1e3+10;
- 12 using namespace std;
- 13 int f[maxn];
- 14 int find(int x)
- 15 {
- 16 if(f[x]!=x)
- 17 f[x]=find(f[x]);
- 18 return f[x];
- 19 }
- 20 inline void join(int x,int y)
- 21 {
- 22 int dx=f[x],dy=f[y];
- 23 if(dx!=dy)
- 24 f[dy]=dx;
- 25 }
- 26 struct Edge
- 27 {
- 28 int to,Next;
- 29 int value;
- 30 }edge[maxn];
- 31 int tot1;
- 32 int head1[maxn];
- 33 inline void add_edge(int u,int v,int w)
- 34 {
- 35 edge[tot1].to=v;
- 36 edge[tot1].value=w;
- 37 edge[tot1].Next=head1[u];
- 38 head1[u]=tot1++;
- 39 }
- 40 int vist[maxn];
- 41 int dis[maxn];
- 42 // 预处理每个点到根节点的距离
- 43 void dfs(int u,int len)
- 44 {
- 45 dis[u]=len;
- 46 vist[u]=1;
- 47 for(int i=head1[u];~i;i=edge[i].Next)
- 48 {
- 49 int v=edge[i].to;
- 50 if(!vist[v])
- 51 dfs(v,len+edge[i].value);
- 52 }
- 53 }
- 54 struct Query
- 55 {
- 56 int to,nex;
- 57 int index;
- 58 }query[maxn];
- 59 int head2[maxn];
- 60 int tot2;
- 61 inline void add_query(int u,int v,int index)
- 62 {
- 63 query[tot2].to=v;
- 64 query[tot2].index=index;
- 65 query[tot2].nex=head2[u];
- 66 head2[u]=tot2++;
- 67 query[tot2].to=u;
- 68 query[tot2].index=index;
- 69 query[tot2].nex=head2[v];
- 70 head2[v]=tot2++;
- 71 }
- 72 int vis[maxn];
- 73 int fa[maxn];
- 74 int ans[maxn];
- 75 void LCA(int u)
- 76 {
- 77 fa[u]=u;
- 78 vis[u]=1;
- 79 for(int i=head1[u];~i;i=edge[i].Next)
- 80 {
- 81 int v=edge[i].to;
- 82 if(vis[v])
- 83 continue;
- 84 LCA(v);
- 85 join(u,v);
- 86 fa[find(u)]=u;
- 87 }
- 88 for(int i=head2[u];~i;i=query[i].nex)
- 89 {
- 90 int v=query[i].to;
- 91 if(vis[v])
- 92 ans[query[i].index]=fa[find(v)];
- 93 }
- 94 }
- 95 inline void init(int n)
- 96 {
- 97 tot1=tot2=0;
- 98 ms(head1,-1);
- 99 ms(head2,-1);
- 100 ms(vis,0);
- 101 ms(vist,0);
- 102 ms(fa,0);
- 103 ms(dis,0);
- 104 for(int i=1;i<=n;i++)
- 105 f[i]=i;
- 106 }
- 107 int x[maxn],y[maxn];
- 108 int main(int argc, char const *argv[])
- 109 {
- 110 #ifndef ONLINE_JUDGE
- 111 freopen("/home/wzy/in.txt", "r", stdin);
- 112 freopen("/home/wzy/out.txt", "w", stdout);
- 113 srand((unsigned int)time(NULL));
- 114 #endif
- 115 ios::sync_with_stdio(false);
- 116 cin.tie(0);
- 117 int n,m,q;
- 118 while(cin>>n>>m)
- 119 {
- 120 init(n);
- 121 int u,v,w;
- 122 char ch[3];
- 123 for(int i=0;i<m;i++)
- 124 cin>>u>>v>>w>>ch,add_edge(u,v,w),add_edge(v,u,w);
- 125 dfs(1,0);
- 126 cin>>q;
- 127 for(int i=0;i<q;i++)
- 128 cin>>x[i]>>y[i],add_query(x[i],y[i],i);
- 129 LCA(1);
- 130 for(int i=0;i<q;i++)
- 131 cout<<dis[x[i]]+dis[y[i]]-2*dis[ans[i]]<<endl;
- 132 }
- 133 #ifndef ONLINE_JUDGE
- 134 cerr<<"Time elapsed: "<<1.0*clock()/CLOCKS_PER_SEC<<" s."<<endl;
- 135 #endif
- 136 return 0;
- 137 }
POJ 1986:Distance Queries的更多相关文章
- POJ 1986:Distance Queries(倍增求LCA)
http://poj.org/problem?id=1986 题意:给出一棵n个点m条边的树,还有q个询问,求树上两点的距离. 思路:这次学了一下倍增算法求LCA.模板. dp[i][j]代表第i个点 ...
- poj-1986 Distance Queries(lca+ST+dfs)
题目链接: Distance Queries Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 11531 Accepted ...
- POJ 1986 Distance Queries(Tarjan离线法求LCA)
Distance Queries Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 12846 Accepted: 4552 ...
- poj 1986 Distance Queries LCA
题目链接:http://poj.org/problem?id=1986 Farmer John's cows refused to run in his marathon since he chose ...
- 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 ...
- 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两点距离树
标题来源: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 ( LCA 倍增 )
POJ.1986 Distance Queries ( LCA 倍增 ) 题意分析 给出一个N个点,M条边的信息(u,v,w),表示树上u-v有一条边,边权为w,接下来有k个询问,每个询问为(a,b) ...
随机推荐
- JavaBean内省与BeanInfo
Java的BeanInfo在工作中并不怎么用到,我也是在学习spring源码的时候,发现SpringBoot启动时候会设置一个属叫"spring.beaninfo.ignore", ...
- c++基础知识03
1.嵌套循环案例--九九乘法表 int main() { //利用嵌套循环乘法口诀表 for (int n = 1; n <= 9; n++) { for (int m = 1; m <= ...
- java输入代码
import java.util.Scanner; public class Demo59 { public static void main(String[] args) { / ...
- linux 实用指令时间日期类
linux 使用指令时间日期类 data 显示当前日期 基本语法 date 显示当前时间 date+%Y 显示当前年份 date+%m 显示当前月份 date+%d 显示当前是哪一天 date &qu ...
- 重学Git(一)
一.最最最基础操作 # 初始化仓库 git init # 添加文件到暂存区 git add readme.md # 提交 git commit -m 'wrote a readme file' 二.简 ...
- 12-gauge/bore shotgun
12-gauge/bore shotgun不是弹夹(magazine)容量为12发的霰(xian)弹枪.[LDOCE]gauge - a measurement of the width or thi ...
- 【leetocode】55. Jump Game
You are given an integer array nums. You are initially positioned at the array's first index, and ea ...
- 【Word】自动化参考文献-交叉引用
第一步:设置参考文献标号 开始-定义新编号格式中,定义参考文献式的方框编号: 这里注意不要把他原来的数字去掉 第二步:选择交叉引用 插入-交叉引用: 第三步:更新标号 如果更新标号,使用右键-更新域. ...
- [PROC FREQ] 单组率置信区间的计算
本文链接:https://www.cnblogs.com/snoopy1866/p/15674999.html 利用PROC FREQ过程中的binomial语句可以很方便地计算单组率置信区间,SAS ...
- 严重危害警告!Log4j 执行漏洞被公开!
12 月 10 日凌晨,Apache 开源项目 Log4j2 的远程代码执行漏洞细节被公开,漏洞威胁等级为:严重. Log4j2 是一个基于 Java 的日志记录工具.它重写了 Log4j 框架,引入 ...