本题目输入格式同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. 谈谈对MVC的理解

    MVC是Model-View-Controler的简称,即模型-视图-控制器.其实MVC是一种设计模式,它强制性的把应用程序的输入.处理和输出分开.MVC中的模型.视图.控制器它们分别承担着不同的任务 ...

  2. jpg图片在IE6、IE7和IE8下不显示解决办法

    坑人的IE浏览器,花了我一个小时才找到原因. 原因:IE内核不能渲染CMYK模式的jpg图片,需要转换为RGB模式. 在photoshop里点击菜单栏—图像—RGB模式就行了 引用:http://lg ...

  3. django-south

    python manage.py schemamigration youappname --initial # --initial在数据库创建models定义的表,以及South需要的south_mi ...

  4. 自带TabBar选中图片设置问题

    设置为UIImageRenderingModeAlwaysOriginal 就会显示出选中状态的图片.当然普通状态的也需要设置. UINavigationController *nav =({ UIN ...

  5. linux打开端口

    客户那边有台服务器同一个局域网中都无法访问,排除lamp环境问题,发现时服务器中的防火墙没有开启80端口.于是去网上搜索了一下,在脚本之家看到一种添加代码的方法  代码如下 复制代码 vi /etc/ ...

  6. Eclipse Indigo 3.7.0 安装GIT插件提示 requires 'bundle org.eclipse.team.core(转)

    文章参考来源:http://showlike.iteye.com/blog/1958538 错误提示: Cannot complete the install because one or more ...

  7. 解决sharepoint 2010 用户配置文件同步服务 正在启动

    用户配置文件同步服务一直显示“正在启动”,而且无法停止,如下办法可以停止这个服务: 在sharepoint power shell 中执行下面的命令: Get-spserviceinstance 获取 ...

  8. P3408: [Usaco2009 Oct]Heat Wave 热浪

    水题,裸的最短路. ; type link=^node; node=record t,d:longint; f:link; end; var n,m,s,i,j,u,v,w,max:longint; ...

  9. asp.net自带的异步刷新控件使用

    一直都是使用jquery的$.ajax,由于刚刚加入的公司是用asp.net的,webform与之前的ajax加在一起显得很混乱,后来发现asp.net已经封装了一下ajax功能,就查了一下,并且做了 ...

  10. [转载]EF Code First 学习笔记:约定配置

    要更改EF中的默认配置有两个方法,一个是用Data Annotations(在命名空间System.ComponentModel.DataAnnotations;),直接作用于类的属性上面;还有一个就 ...