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的更多相关文章

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

    http://poj.org/problem?id=1986 题意:给出一棵n个点m条边的树,还有q个询问,求树上两点的距离. 思路:这次学了一下倍增算法求LCA.模板. dp[i][j]代表第i个点 ...

  2. poj-1986 Distance Queries(lca+ST+dfs)

    题目链接: Distance Queries Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 11531   Accepted ...

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

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

  4. poj 1986 Distance Queries LCA

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

  5. 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 ...

  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 LCA两点距离树

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

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

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

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

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

随机推荐

  1. Kubernetes:应用自动扩容、收缩与稳定更新

    在前面我们已经学习到了 Pod 的扩容.滚动更新等知识,我们可以手动为 Deployment 等设置 Pod 副本的数量,而这里会继续学习 关于 Pod 扩容.收缩 的规则,让 Pod 根据节点服务器 ...

  2. Java偏向锁浅析

    偏向锁的定义 顾名思义,偏向锁会偏向第一个访问锁的线程. 如果在接下来的运行过程中,该锁没有被其他线程访问,这持有偏向锁的线程将永远不需要同步 如果在运行过程中,遇到了其他线程抢占锁,则持有偏向锁的线 ...

  3. 零基础学习java------30---------wordCount案例(涉及到第三种多线程callable)

    知识补充:多线程的第三种方式 来源:http://www.threadworld.cn/archives/39.html 创建线程的两种方式,一种是直接继承Thread,另外一种就是实现Runnabl ...

  4. 【JAVA开发】浅析双亲委派机制

    双亲委派机制存在的意义 双亲委派只是一种说法,个人觉得叫单亲委派更合适,因为向上传递的父类只有一个,估计只是翻译过来的,形成的一种习惯,大家可以当做单亲委派 四种加载器都是用于类的加载,只是加载的对象 ...

  5. Java中方法的定义与使用

    Java中方法的定义与使用 1.方法的定义: 方法是一段可以被重复调用的代码块. 方法的声明: public static 方法返回值 方法名([参数类型 变量--]){ 方法代码体: return ...

  6. Linux学习 - 文本编辑器Vim

    一.Vim工作模式 二.命令 插入 a 光标后插入 A 光标所在行尾插入 i 光标前插入 I 光标所在行首插入 o 光标下插入新行 O 光标上插入新行   删除 x 删除光标处字符 nx 删除光标处后 ...

  7. 【Linux】【Basis】【网络】网络相关的内核参数

    Linux系统内核设置优化tcp网络,# vi /etc/sysctl.conf,添加以下内容 net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies.当出现SYN等待 ...

  8. Type of 'this' pointer in C++

    In C++, this pointer is passed as a hidden argument to all non-static member function calls. The typ ...

  9. 常用 HTTP 状态码

    下面是列举的我在项目中用到过的一些 HTTP 状态码,当然,在具体的使用中并不是用到的状态码越多越好,需要结合自己项目情况来选用适合自己的 HTTP 状态码.   HTTP 状态码 含义说明 200 ...

  10. Mysql资料 mysqldump

    目录 一.简介 备份过程 优缺点 命令使用 myisam引擎 二.安装 配置 日志 三.日常使用 备份全库 备份单个库(带建立库的语句) 备份单个库(不自动建立库) 备份表合集 从全备中恢复单个库 其 ...