本题目输入格式同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. [转]关于VC预定义常量_WIN32,WIN32,_WIN64

      VC2012 下写 Windows 程序时,有时需要判断编译环境.在之前的文章<判断程序是否运行在 Windows x64 系统下.>里说过如何在运行期间判断系统环境,但在编译时如何判 ...

  2. SQL1092N The requested command or operation failed because the user ID does not have the authority to perform the requested command or operation.

    1.前一天安装号db2后,做了如下处理: ************************************************************ 修改 /etc/sudoers 文件 ...

  3. 源码解析之setContentView

    分享一下我以前学习时做到PPT中的一部分. 不难看出其实设置布局是由PhoneWindow来完成的. 然而我们要记住DecorView: 包括:状态栏,标题栏,内容 phoneWindow -> ...

  4. poj 1679 The Unique MST

    题目连接 http://poj.org/problem?id=1679 The Unique MST Description Given a connected undirected graph, t ...

  5. postgresql 连接数

    改文件 postgresql.conf 里的 #max_connections=32 为 max_connections=1024 以及另外相应修改 share_buffer 参数. 执行SELECT ...

  6. Go循环引用问题

    在Go中,不支持循环引用,即package a引用了packageb以后,package b就不能引用package a了. 最简单的场景: package a中定义context.go用来保存上下文 ...

  7. php5调用web service (笔者测试成功)

    转自:http://www.cnblogs.com/smallmuda/archive/2010/10/12/1848700.html 感谢作者分享 工作中需要用php调用web service接口, ...

  8. 最基础的Hash

    type thash=^node; node=record state:longint; next:thash; end; var a,i:longint; p:thash; hash:..]of t ...

  9. How to compile and install NCAR Command Language on IBM PowerPC 64 --- NCL编译安装步骤

    作者:Sinsonglew 出处:http://www.cnblogs.com/sinsonglew 欢迎转载,也请保留这段声明.thanks :) 注记:NCL官方依赖安装包全集列表.官方源码编译指 ...

  10. 搭建SpringMVC+MyBatis开发框架一

    大部分 Java 应用都是 Web 应用,展现层是 Web 应用不可忽略的重要环节.Spring 为展现层提供了一个优秀的 Web 框架—— Spring MVC.和众多其他 Web 框架一样,它基于 ...