POJ 1986 Distance Queries (最近公共祖先,tarjan)
本题目输入格式同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)的更多相关文章
- 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 意甲冠军:给你一棵树 q第二次查询 每次你问两个点之间的距离 思路:对于2点 u v dis(u,v) = dis(root,u) + d ...
- 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 【输入YY && LCA(Tarjan离线)】
任意门:http://poj.org/problem?id=1986 Distance Queries Time Limit: 2000MS Memory Limit: 30000K Total ...
- 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离线法求LCA)
Distance Queries Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 12846 Accepted: 4552 ...
- POJ 1986 Distance Queries(LCA Tarjan法)
Distance Queries [题目链接]Distance Queries [题目类型]LCA Tarjan法 &题意: 输入n和m,表示n个点m条边,下面m行是边的信息,两端点和权,后面 ...
- POJ - 1986 Distance Queries(离线Tarjan算法)
1.一颗树中,给出a,b,求最近的距离.(我没考虑不联通的情况,即不是一颗树的情况) 2.用最近公共祖先来求, 记下根结点到任意一点的距离dis[],这样ans = dis[u] + dis[v] - ...
- 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 ...
随机推荐
- 关于activity_main.xml与fragment_main.xml
第一种解决办法 新版安装SDK文件一开始有两个XML文件,activity_main.xml和fragment_main.xml,不习惯的可以这样处理:1.删除fragment_main.xml整个文 ...
- 谈谈对MVC的理解
MVC是Model-View-Controler的简称,即模型-视图-控制器.其实MVC是一种设计模式,它强制性的把应用程序的输入.处理和输出分开.MVC中的模型.视图.控制器它们分别承担着不同的任务 ...
- Supporting Connected Routes to Subnet Zero
Supporting Connected Routes to Subnet Zero IOS allows the network engineer to tell a router to eithe ...
- char const*, char*const, const char *const的区别
C++标准规定,const关键字放在类型或变量名之前等价的.所以,const char*和 char const*是一样的. const char* //常量指针---指向常量的指针----指针指 ...
- 关于Haproxy安装和配置:负载配置【haproxy.cfg】问题记录
1. 存放地址: more /etc/haproxy/haproxy.cfg ps -ef | grep haproxy 看看有没有haproxy的进程就是了 或者看看服务器的23306的端口有没有 ...
- 三种嵌入式web服务器(Boa / lighttpd / shttpd)的 linux移植笔记
一:移植Boa(web服务器)到嵌入式Linux系统 一.Boa程序的移植 1.下载Boa源码 下载地址: http://www.boa.org/ 目前最新发行版本: 0.94.13 ...
- 第三方登录开发-Facebook
这次这个项目要分别可以使用新浪微博,qq互联以及Facebook和Twitter授权登录 facebook目前只支持oauth2技术,个人理解其工作流程是当用户想访问当前网站,却不想注册账号,此时当前 ...
- UISwitch swift
// // ViewController.swift // UILabelTest // // Created by mac on 15/6/23. // Copyright (c) 2015年 fa ...
- java无符号移位(>>>)和有符号移位(>>)
java中>>(<<)表示有符号的移位.<<<(>>>)表示无符号移位 如: int num = 22; 二进制是0001 0110, nu ...
- ubuntu 13.04 163源(亲测可用)
# deb cdrom:[Ubuntu )]/ trusty main restricted # See http://help.ubuntu.com/community/UpgradeNotes f ...