POJ 1986 Distance Queries(Tarjan离线法求LCA)
Time Limit: 2000MS | Memory Limit: 30000K | |
Total Submissions: 12846 | Accepted: 4552 | |
Case Time Limit: 1000MS |
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
题目连接:POJ 1986
简单模版题,一棵树中两点的距离$d(u,v)$可以用$d[u]+d[v]-2*d[lca(u,v)]$来求得,其中$d_i$是你设定的根到某一点$i$的距离,那显然首先随便找个点进行最短路或者直接DFS获得d数组,再Tarjan得出答案
代码:
- #include <stdio.h>
- #include <iostream>
- #include <algorithm>
- #include <cstdlib>
- #include <sstream>
- #include <cstring>
- #include <bitset>
- #include <string>
- #include <deque>
- #include <stack>
- #include <cmath>
- #include <queue>
- #include <set>
- #include <map>
- using namespace std;
- #define INF 0x3f3f3f3f
- #define CLR(arr,val) memset(arr,val,sizeof(arr))
- #define LC(x) (x<<1)
- #define RC(x) ((x<<1)+1)
- #define MID(x,y) ((x+y)>>1)
- typedef pair<int,int> pii;
- typedef long long LL;
- const double PI=acos(-1.0);
- const int N=40010;
- struct edge
- {
- int to;
- int nxt;
- int w;
- };
- struct query
- {
- int to;
- int nxt;
- int id;
- };
- edge E[N<<1];
- query Q[N<<1];
- int head[N],rhead[N],tot,rtot;
- int d[N],dx[N],vis[N],in[N];
- int pre[N],ances[N];
- void init()
- {
- CLR(head,-1);
- CLR(rhead,-1);
- tot=rtot=0;
- CLR(d,0);
- for (int i=0; i<N; ++i)
- {
- pre[i]=i;
- ances[i]=0;
- }
- CLR(vis,0);
- CLR(in,0);
- CLR(dx,0);
- }
- int Find(int n)
- {
- if(pre[n]==n)
- return n;
- return pre[n]=Find(pre[n]);
- }
- inline void add(int s,int t,int d)
- {
- E[tot].to=t;
- E[tot].w=d;
- E[tot].nxt=head[s];
- head[s]=tot++;
- }
- inline void addquery(int s,int t,int id)
- {
- Q[rtot].id=id;
- Q[rtot].to=t;
- Q[rtot].nxt=rhead[s];
- rhead[s]=rtot++;
- }
- void LCA(int u)
- {
- vis[u]=1;
- ances[u]=u;
- int i,v;
- for (i=head[u]; ~i; i = E[i].nxt)
- {
- v = E[i].to;
- if(!vis[v])
- {
- LCA(v);
- pre[v]=u;
- ances[Find(u)]=u;
- }
- }
- for (i=rhead[u]; ~i; i = Q[i].nxt)
- {
- v=Q[i].to;
- if(vis[v])
- dx[Q[i].id]=d[u]+d[v]-(d[ances[Find(v)]]<<1);
- }
- }
- void dfs(int u,int fa,int sum)
- {
- d[u]=sum;
- for (int i=head[u]; ~i; i = E[i].nxt)
- {
- int v=E[i].to;
- if(v!=fa)
- dfs(v,u,sum+E[i].w);
- }
- }
- int main(void)
- {
- int n,m,a,b,c,i,k;
- char nouse[5];
- while (~scanf("%d%d",&n,&m))
- {
- init();
- for (i=0; i<m; ++i)
- {
- scanf("%d%d%d%s",&a,&b,&c,nouse);
- add(a,b,c);
- add(b,a,c);
- ++in[b];
- }
- scanf("%d",&k);
- for (i=0; i<k; ++i)
- {
- scanf("%d%d",&a,&b);
- addquery(a,b,i);
- addquery(b,a,i);
- }
- for (i=1; i<=n; ++i)
- {
- if(!in[i])
- {
- dfs(i,-1,0);
- LCA(i);
- break;
- }
- }
- for (i=0; i<k; ++i)
- printf("%d\n",dx[i]);
- }
- return 0;
- }
POJ 1986 Distance Queries(Tarjan离线法求LCA)的更多相关文章
- POJ - 1986 Distance Queries(离线Tarjan算法)
1.一颗树中,给出a,b,求最近的距离.(我没考虑不联通的情况,即不是一颗树的情况) 2.用最近公共祖先来求, 记下根结点到任意一点的距离dis[],这样ans = dis[u] + dis[v] - ...
- 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) ...
- POJ 1986 Distance Queries LCA两点距离树
标题来源:POJ 1986 Distance Queries 意甲冠军:给你一棵树 q第二次查询 每次你问两个点之间的距离 思路:对于2点 u v dis(u,v) = dis(root,u) + d ...
- 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 1986 Distance Queries (Tarjan算法求最近公共祖先)
题目链接 Description Farmer John's cows refused to run in his marathon since he chose a path much too lo ...
- POJ 1986 Distance Queries (最近公共祖先,tarjan)
本题目输入格式同1984,这里的数据范围坑死我了!!!1984上的题目说边数m的范围40000,因为双向边,我开了80000+的大小,却RE.后来果断尝试下开了400000的大小,AC.题意:给出n个 ...
- poj 1986 Distance Queries LCA
题目链接:http://poj.org/problem?id=1986 Farmer John's cows refused to run in his marathon since he chose ...
随机推荐
- 简单的实现UIpicker上面的取消确定按钮
1 因为我用的xib实现的添加picker 和textfiled的, @interface ViewController : UIViewController<UITextFieldDelega ...
- 百度地图API使用记录
用户数据图层的总教程: 就是把用户数据存到LBS云里面,应用从云里面读数据 http://developer.baidu.com/map/jsdevelop-9.htm 上传数据的地方: http:/ ...
- BZOJ4584 : [Apio2016]赛艇
首先将值域离散化成$O(n)$个连续段. 设$f[i][j][k]$表示第$i$个学校派出的数量在第$j$个连续段,在第$j$个连续段一共有$k$个学校的方案数.用组合数以及前缀和转移即可. 时间复杂 ...
- 使用Adobe Edge Inspect在各种设备中轻松测试同一页面
有过移动网站开发经历的开发者都知道,在各种设备中测试同一页面是一项非常繁琐的工作.现在,我们可以使用Adobe Edge Inspect来简化这一工作.如果使用Edge Inspect,可以在各种设备 ...
- ACM 懒省事的小明
懒省事的小明 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 小明很想吃果子,正好果园果子熟了.在果园里,小明已经将所有的果子打了下来,而且按果子的不同种 ...
- ACM 变态最大值
变态最大值 时间限制:1000 ms | 内存限制:65535 KB 难度:1 描述 Yougth讲课的时候考察了一下求三个数最大值这个问题,没想到大家掌握的这么烂,幸好在他的帮助下大家算是解 ...
- 【CodeVS】p1299 切水果
题目描述 Description 简单的说,一共N个水果排成一排,切M次,每次切[L,R]区间的所有水果(可能有的水果被重复切),每切完一次输出剩下水果数量 数据已重新装配,不会出现OLE错误 时限和 ...
- 【hdu】p1754I Hate It
I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- Android -- 简单的图片浏览器
1. 效果图
- NOI模拟赛Day3
终于A题啦鼓掌~开心~ 开考看完题后,觉得第二题很好捏(傻叉上线 搞到十一点准备弃疗了然后突然发现我会做第一题 于是瞎码了码,就去准备饭票了... 好了,停止扯淡(就我一个我妹子每天不说话好难受QAQ ...