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 ...
随机推荐
- 怎么提高Jquery性能
很久没有关注jQuery了,最近重新看了一下,看到一些不错的文章,转来坐一下笔记. 其内容和一些新提供的方法还是很多有值得学习的地方. 1. 使用最新版本的jQuery jQuery的版本更新很快,你 ...
- Codeforces 653D Delivery Bears(最大流)
题目大概说有一张n个点m条边的简单有向图,每条边只能允许一定总量的货物通过.要让x只熊从1点到n点运送货物,每只熊都要运送且运送的货物重量都一样,求该重量的最大值. 二分重量判断是否成立. 如果已知重 ...
- js定时相关函数:
定时相关函数: mytime= setTimeout(vCode, iMilliSeconds [, sLanguage]) -- 单次定时执行指定函数 clearTimeout(iTimeoutID ...
- word多级编号,如何让第一级为大写“一”,其他级别均为小写1.
自定义里面设置了第一级为大写,2级.3级首字跟着变为大写,是因为2.3级没有勾选"正规形式编号",如图:
- CentOS6.4 增加一个SFTP上传的用户
#创建sftp组 groupadd sftp #创建一个用户dsideal useradd -g sftp -s /bin/false dsideal #设置dsideal用户的密码 passwd d ...
- ACM Greedy Mouse
Greedy Mouse 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 A fat mouse prepared M pounds of cat food,read ...
- CDOJ 1431 不是图论 Label:Tarjan || Kosarajn
Time Limit:1000MS Memory Limit:65535KB 64bit IO Format:%lld & %llu Description 给出一个nn个点, ...
- BZOJ 1179 Atm 题解
BZOJ 1179 Atm 题解 SPFA Algorithm Tarjan Algorithm Description Input 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来 ...
- 【BZOJ】1524: [POI2006]Pal
题意 给出\(n\)个回文串\(s_i(\sum_{i=1}^{n} |s_i| \le 2000000)\)求如下二元组\((i, j)\)的个数\(s_i + s_j\)仍然是回文串. 分析 这道 ...
- linq中join的用法
join方法 public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>( this IEnu ...