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 ...
随机推荐
- 使用wget
下载整个网站 需要下载某个目录下面的所有文件: wget -c -r -np -k -L -p url 有用到外部域名的图片或连接,如果需要同时下载就要用-H参数: wget -np -nH -r - ...
- wpf,CollectionViewSource,使用数据过滤 筛选 功能。
class TextListBoxVMpublic : ViewModelBase { public TextListBoxVMpublic() { var list = this.GetEmploy ...
- 使用Soapui测试webservice接口
本来想自己写一个的,但下面这个资料比较详细(截图和步骤细节),就省事了,具体内容见: http://blog.csdn.net/oracle_microsoft/article/details/568 ...
- ural 2065. Different Sums
2065. Different Sums Time limit: 1.0 secondMemory limit: 64 MB Alex is a very serious mathematician ...
- 数据结构:后缀自动机 WJMZBMR讲稿的整理和注释
链接放在这里,有点难理解,至少我个人是的. 后缀自动机是一种有限状态自动机,其功能是识别字符串是否是母串的后缀.它能解决的问题当然不仅仅是判断是不是后缀这种事,跟字符串的连续子串有关的问题都可以往这个 ...
- BZOJ 1059 & 二分图匹配
题意: 判断一个黑白染色的棋盘能否通过交换行或列使对角线上都是黑色. SOL: 真是有点醉...这种问题要么很神要么很水...第一眼感觉很水但就是不造怎么做...想了10分钟怎么感觉就是判断个数够不够 ...
- js两个小技巧【看到了就记录一下】
1.不声明第三个变量实现交换 ,b=; a=[b,b=a][];//执行完这句代码之后 a的值为2 b的值为1了 2.&&和||的用法 (学会了立马感觉高大尚了吧) ; //传统if语 ...
- Android studio 签名使用转
来自http://www.cnblogs.com/xiwix/archive/2012/04/15/2447910.html 本文主要讲解Android应用程序签名相关的理论知识,包括:什么是签名.为 ...
- JAVA生成条形码
1.下载生成条形码所需要的jar包barcode4j.jar: 2.java生成条形码代码 import java.awt.image.BufferedImage;import java.io.Fil ...
- 李洪强iOS经典面试题132-版本控制
面试过程中,可能会问及一些关于版本控制的问题,理解下SVN和Git的原理,记住常用命令即可. SVN SVN 是集中式源代码管理工具 概念: 1> Repository 代码仓库,保存代码的仓库 ...