本题目输入格式同1984,这里的数据范围坑死我了!!!1984上的题目说边数m的范围40000,因为双向边,我开了80000+的大小,却RE。
后来果断尝试下开了400000的大小,AC。
题意:给出n个点,m条边。
  接下来m行,每行对应u,v,len,字符(字符表示v位于u的哪个方向,在本题没有丝毫用处)
  表示u和v的路径长度为len。注意本题是双向边!
  给出k个查询,让你求两点间的距离。
思路:可以这样处理:先处理出每个节点i到根的距离dist[i]。
  设根节点1到a的路径和1到b的路径的最后一个相同的节点为u,即a和b的最近公共祖先。
  那么a和b之间的路径为au+ub。
  au+ub=au+dis[u]+ub+dis[u]-2*dis[u]=dis[a]+dis[b]-2*dis[LCA(a,b)]
  求最近公共祖先用tarjan算法

还有就是一开始不知道如何将两点之间的距离和对应的查询联系起来,参考了别人的思路后,恍然大悟。
在存储所要查询的内容时,同时记录对应的编号,之后再求LCA时只要将距离存入索引为对应编号的数组中去即可,详细情况见代码吧。

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <queue>
#include <math.h>
#include <map> using namespace std;
const int maxn=;
const int INF=0x3f3f3f3f;
int n,m,k;
int head[maxn];
int tot=;
int dis[maxn]; //存储节点到根节点1的距离
int vis[maxn]={}; //用于LCA中的标记
int vis2[maxn]={}; //用于标记是否被访问过
int result[]; struct Query{
int u;
int id; //该查询对应的编号
}; vector<Query>link[maxn]; struct Edge{
int next,to,length;
}edge[maxn*];
//POJ1984上面说边数大小最多40000,由于双向边,我开了80000+,结果RE,后来开了10倍,才AC。。。 void add(int u,int v,int l){
edge[tot].next=head[u];
edge[tot].to=v;
edge[tot].length=l;
head[u]=tot++; edge[tot].next=head[v];
edge[tot].to=u;
edge[tot].length=l;
head[v]=tot++;
}
struct UF{
int fa[maxn];
void init(){
for(int i=;i<maxn;i++)
fa[i]=i;
}
int find_root(int x){
if(fa[x]!=x)
fa[x]=find_root(fa[x]);
return fa[x];
}
void Union(int u,int v){
int x=find_root(u);
int y=find_root(v);
fa[y]=x;
}
}uf; void LCA(int u){
vis2[u]=;
for(int k=head[u];k!=-;k=edge[k].next){
int v=edge[k].to;
if(!vis2[v]){
LCA(v);
uf.Union(u,v);
}
}
int v,idx,anc;
vis[u]=;
for(int i=;i<link[u].size();i++){
v=link[u][i].u;
if(vis[v]){
//idx是u和v所对应的第几个询问
idx=link[u][i].id;
anc=uf.fa[uf.find_root(v)];
result[idx]=dis[u]+dis[v]-*dis[anc];
}
}
}
void dfs(int u,int l){
vis2[u]=;
dis[u]=l;
for(int k=head[u];k!=-;k=edge[k].next){
if(!vis2[edge[k].to])
dfs(edge[k].to,l+edge[k].length);
}
}
int main()
{
int u,v,l;
char str[];
memset(dis,,sizeof(dis));
memset(head,-,sizeof(head));
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++){
scanf("%d%d%d%s",&u,&v,&l,str);
add(u,v,l);
add(v,u,l);
}
cin>>k;
Query tmp;
for(int i=;i<=k;i++){
scanf("%d%d",&u,&v);
tmp.u=v;tmp.id=i; //这个方法妙啊,在存储查询内容时,记录下对应的编号。
link[u].push_back(tmp);
tmp.u=u;
link[v].push_back(tmp);
}
memset(vis2,,sizeof(vis2));
//先求各节点到根节点的距离
dfs(,);
uf.init();
memset(vis2,,sizeof(vis2));
//LCA求最近公共祖先
LCA();
for(int i=;i<=k;i++){
printf("%d\n",result[i]);
}
return ;
}

POJ 1986 Distance Queries (最近公共祖先,tarjan)的更多相关文章

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

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

  2. POJ 1986 Distance Queries LCA两点距离树

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

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

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

  4. POJ 1986 Distance Queries 【输入YY && LCA(Tarjan离线)】

    任意门:http://poj.org/problem?id=1986 Distance Queries Time Limit: 2000MS   Memory Limit: 30000K Total ...

  5. POJ 1986 Distance Queries (Tarjan算法求最近公共祖先)

    题目链接 Description Farmer John's cows refused to run in his marathon since he chose a path much too lo ...

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

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

  7. POJ 1986 Distance Queries(LCA Tarjan法)

    Distance Queries [题目链接]Distance Queries [题目类型]LCA Tarjan法 &题意: 输入n和m,表示n个点m条边,下面m行是边的信息,两端点和权,后面 ...

  8. POJ - 1986 Distance Queries(离线Tarjan算法)

    1.一颗树中,给出a,b,求最近的距离.(我没考虑不联通的情况,即不是一颗树的情况) 2.用最近公共祖先来求, 记下根结点到任意一点的距离dis[],这样ans = dis[u] + dis[v] - ...

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

随机推荐

  1. C扩展 C++回顾到入门

    引言 C扩展也称C++, 是一个复(za)杂(ji)优(ken)秀(die)的语言. 本文通过开发中常用C++方式来了解和回顾C++这么语言. C++看了较多的书但还是觉得什么都不会. 只能说自己还付 ...

  2. Linux下编译内核配置选项简介

    Code maturity level options代码成熟度选项 Prompt for development and/or incomplete code/drivers 显示尚在开发中或尚未完 ...

  3. 九度oj 1528 最长回文子串

    原题链接:http://ac.jobdu.com/problem.php?pid=1528 小白书上的做法,不过这个还要简单些... #include<algorithm> #includ ...

  4. Android 文档之viewAnimator

    一.结构 public class ViewAnimator extends FrameLayout java.lang.Object android.view.View android.view.V ...

  5. Tutorial: Analyzing sales data from Excel and an OData feed

    With Power BI Desktop, you can connect to all sorts of different data sources, then combine and shap ...

  6. MVC4.0 利用HandleErrorAttribute和log4net实现记录异常日志功能

    1.MVC4.0中HandleErrorAttribte已经帮我们处理了异常问题,当我们新建一个非空的MVC项目时候,在FilterConfig中会发现这样的代码 public class Filte ...

  7. c/c++常用代码 -- ini文件操作

    #pragma once #include <string> #include <sstream> typedef std::basic_string<TCHAR> ...

  8. C# 生成XML 多级节点

    直接上代码: 在应用程序中 class Program { //public static JsonServiceClient Service = new JsonServiceClient(Conf ...

  9. Datawarehouse

  10. ActiveX控件的基本操作方法以及如何在VS2010下使用控件

    在此,小编就介绍下ActiveX控件的基本操作方法以及如何在VS2010下使用控件,我们以一个程序为例, (1)      打开VS2010编译器(右键以管理员身份运行,因为ActiveX需要注册), ...