zoj 3195(LCA加强版)
https://www.cnblogs.com/violet-acmer/p/9686774.html
题意:
给一个无根树,有q个询问,每个询问3个点(a,b,c),问将这3个点连起来,距离最短是多少。
题解:
我的思路:
(1)分别求出Lca(a,b),Lca(a,c),Lca(b,c);
(2)找到三个Lca( )中深度最深的那个节点(此处假设Lca(a,b)深度最深),设变量 res = dist[a]+dist[b]-2*dist[Lca(a,b)];
(3)求出Lca(a,b)与c的最近公共祖先,res += dist[c]+dist[Lca(a,b)]-2*dist[Lca(a,b,c)];
参考大佬题解思路:
分别求LCA(a,b),LCA(a,c),LCA(b,c),和对应的距离,然后3个距离相加再除以2就是这个询问的结果。
AC代码:
晚上看了LCA的RMQ算法的一个题,改了一晚上,貌似理解了,太累了,明天再把这个代码的细节写一下.............
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
#define pb push_back
#define ll long long
#define mem(a,b) (memset(a,b,sizeof a))
const int maxn=5e4+; struct Node
{
int to;
int weight;
Node(int to,int weight):to(to),weight(weight){}
};
vector<Node >edge[maxn];
int n,q;
int fa[][maxn];
int dist[maxn];
int depth[maxn];
void addEdge(int u,int v,int w)
{
edge[u].pb(Node(v,w));
edge[v].pb(Node(u,w));
}
void Init()
{
for(int i=;i < n;++i)
edge[i].clear();
}
void Dfs(int u,int f,int d,int l)
{
fa[][u]=f;
dist[u]=l;
depth[u]=d;
for(int i=;i < edge[u].size();++i)
{
int to=edge[u][i].to;
int w=edge[u][i].weight;
if(to != f)
Dfs(to,u,d+,l+w);
}
}
void Pretreat()
{
Dfs(,-,,);
for(int k=;k+ < ;++k)
for(int u=;u < n;++u)
if(fa[k][u] == -)
fa[k+][u]=-;
else
fa[k+][u]=fa[k][fa[k][u]];
}
int Lca(int u,int v)
{
if(depth[u] > depth[v])
swap(u,v);
int k;
for(k=;(<<k) <= depth[v];++k);
k--;
for(int i=k;i >= ;--i)
if((depth[v]-(<<i)) >= depth[u])
v=fa[i][v];
if(u == v)
return v;
for(int i=k;i >= ;--i)
if(fa[i][v] != - && fa[i][v] != fa[i][u])
{
v=fa[i][v];
u=fa[i][u];
}
return fa[][v];
}
int main()
{
bool flag=false;
while(~scanf("%d",&n))
{
Init();
if(flag)
printf("\n");
flag=true;
for(int i=;i < n;++i)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addEdge(u,v,w);
}
Pretreat();
scanf("%d",&q);
for(int i=;i <= q;++i)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
int res;
int lcaAB=Lca(a,b);
int lcaAC=Lca(a,c);
int lcaBC=Lca(b,c);
if(depth[lcaAB] > depth[min(lcaAC,lcaBC)])
{
res=dist[a]-dist[lcaAB]+dist[b]-dist[lcaAB];
res += dist[lcaAB]-dist[Lca(lcaAB,c)]+dist[c]-dist[Lca(lcaAB,c)];
}
else if(depth[lcaAC] > depth[min(lcaAB,lcaBC)])
{
res=dist[a]-dist[lcaAC]+dist[c]-dist[lcaAC];
res += dist[lcaAC]-dist[Lca(lcaAC,b)]+dist[b]-dist[Lca(lcaAC,b)];
}
else
{
res=dist[b]-dist[lcaBC]+dist[c]-dist[lcaBC];
res += dist[lcaBC]-dist[Lca(lcaBC,a)]+dist[a]-dist[Lca(lcaBC,a)];
}
printf("%d\n",res);
}
}
return ;
}
基于二分的LCA
zoj 3195(LCA加强版)的更多相关文章
- zoj 3195 Design the city LCA Tarjan
题目链接 : ZOJ Problem Set - 3195 题目大意: 求三点之间的最短距离 思路: 有了两点之间的最短距离求法,不难得出: 对于三个点我们两两之间求最短距离 得到 d1 d2 d3 ...
- ZOJ 3195 Design the city LCA转RMQ
题意:给定n个点,下面n-1行 u , v ,dis 表示一条无向边和边权值,这里给了一颗无向树 下面m表示m个询问,问 u v n 三点最短距离 典型的LCA转RMQ #include<std ...
- zoj 3195 Design the city lca倍增
题目链接 给一棵树, m个询问, 每个询问给出3个点, 求这三个点之间的最短距离. 其实就是两两之间的最短距离加起来除2. 倍增的lca模板 #include <iostream> #in ...
- ZOJ 3195 Design the city (LCA 模板题)
Cerror is the mayor of city HangZhou. As you may know, the traffic system of this city is so terribl ...
- zoj——3195 Design the city
Design the city Time Limit: 1 Second Memory Limit: 32768 KB Cerror is the mayor of city HangZho ...
- ZOJ 3195 Design the city 题解
这个题目大意是: 有N个城市,编号为0~N-1,给定N-1条无向带权边,Q个询问,每个询问求三个城市连起来的最小权值. 多组数据 每组数据 1 < N < 50000 1 < Q ...
- zoj 3195
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3320 离线算法RE了.. #include<stdio.h> #i ...
- zoj 3649 lca与倍增dp
参考:http://www.xuebuyuan.com/609502.html 先说题意: 给出一幅图,求最大生成树,并在这棵树上进行查询操作:给出两个结点编号x和y,求从x到y的路径上,由每个结点的 ...
- ZOJ - 3195 Design the city
题目要对每次询问将一个树形图的三个点连接,输出最短距离. 利用tarjan离线算法,算出每次询问的任意两个点的最短公共祖先,并在dfs过程中求出离根的距离.把每次询问的三个点两两求出最短距离,这样最终 ...
随机推荐
- C. Oh Those Palindromes
题意 给以一个字符串,让你重排列,使得回文子串的数目最多 分析 对于一个回文串,在其中加入一些字符并不会使回文子串的个数增加,所以对于相同的字符一起输出即可,我是直接排序 代码 #include< ...
- 第三周作业(三)---WordCounter
需求是这样的.写出一个程序,模仿wc.exe,可以统计出文件的一些信息(比如字符数.单词数目等等) 对于这个程序,我仍然用我从大一学来的C语言写的. 第一步:打开文件 printf("请输入 ...
- Rop框架学习笔记
1. 提供了开发服务平台的解决方案:比如应用认证.会话管理.安全控制.错误模型.版本管理.超时限制 2. 启动:RopServlet截获http请求 配置: <servlet> < ...
- Linux期末总结
Linux内核学习总结 1.计算机是如何工作的? 存储程序计算机工作模型 X86汇编基础 汇编一个简单的C程序分析其汇编指令执行过程 2.操作系统是如何工作的? 三个法宝——存储程序计算机.函数调用堆 ...
- 《Linux内核分析》期终总结&《Linux及安全》期中总结
<Linux内核分析>期终总结&<Linux及安全>期中总结 [李行之 原创作品 转载请注明出处 <Linux内核分析>MOOC课程http://mooc. ...
- Linux内核分析第三周学习总结
Linux内核源码简介 arch/ 该目录中包含和硬件体系结构相关的代码,每种平台占一个相应的目录. 和32位PC相关的代码存放在x86目录下. 每种平台至少包含3个子目录:kernel(存放支持体系 ...
- Linux内核设计与实现 第三章
1. 进程和线程 进程和线程是程序运行时状态,是动态变化的,进程和线程的管理操作都是由内核来实现的. Linux中的进程于Windows相比是很轻量级的,而且不严格区分进程和线程,线程不过是一种特殊的 ...
- 关于五子棋游戏java版
一 题目简介:关于五子棋游戏 二 源码的github链接 https://github.com/marry1234/test/blob/master/五子棋游戏 三.所设计的模块测试用例.测试结果 ...
- 递归拼装Tree结构数据
@Override public List<Map<String, Object>> queryListTree() { List<Map<String,Objec ...
- Java 模仿 C# 字典 一例
List<Map.Entry<Integer, String>> orderStatusList = new ArrayList<Map.Entry<Integer ...