传送门:Problem 3195

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加强版)的更多相关文章

  1. zoj 3195 Design the city LCA Tarjan

    题目链接 : ZOJ Problem Set - 3195 题目大意: 求三点之间的最短距离 思路: 有了两点之间的最短距离求法,不难得出: 对于三个点我们两两之间求最短距离 得到 d1 d2 d3 ...

  2. ZOJ 3195 Design the city LCA转RMQ

    题意:给定n个点,下面n-1行 u , v ,dis 表示一条无向边和边权值,这里给了一颗无向树 下面m表示m个询问,问 u v n 三点最短距离 典型的LCA转RMQ #include<std ...

  3. zoj 3195 Design the city lca倍增

    题目链接 给一棵树, m个询问, 每个询问给出3个点, 求这三个点之间的最短距离. 其实就是两两之间的最短距离加起来除2. 倍增的lca模板 #include <iostream> #in ...

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

  5. zoj——3195 Design the city

    Design the city Time Limit: 1 Second      Memory Limit: 32768 KB Cerror is the mayor of city HangZho ...

  6. ZOJ 3195 Design the city 题解

    这个题目大意是: 有N个城市,编号为0~N-1,给定N-1条无向带权边,Q个询问,每个询问求三个城市连起来的最小权值. 多组数据 每组数据  1 < N < 50000  1 < Q ...

  7. zoj 3195

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3320 离线算法RE了.. #include<stdio.h> #i ...

  8. zoj 3649 lca与倍增dp

    参考:http://www.xuebuyuan.com/609502.html 先说题意: 给出一幅图,求最大生成树,并在这棵树上进行查询操作:给出两个结点编号x和y,求从x到y的路径上,由每个结点的 ...

  9. ZOJ - 3195 Design the city

    题目要对每次询问将一个树形图的三个点连接,输出最短距离. 利用tarjan离线算法,算出每次询问的任意两个点的最短公共祖先,并在dfs过程中求出离根的距离.把每次询问的三个点两两求出最短距离,这样最终 ...

随机推荐

  1. 置换群 Burnside引理 Pólya定理(Polya)

    置换群 设\(N\)表示组合方案集合.如用两种颜色染四个格子,则\(N=\{\{0,0,0,0\},\{0,0,0,1\},\{0,0,1,0\},...,\{1,1,1,1\}\}\),\(|N|= ...

  2. 002-打开文件管理规范-20190406.bat

    rem 002-打开文件管理规范-20190406.bat start /max https://www.cnblogs.com/delphixx/p/10652763.htmlcopy %~0 C: ...

  3. C. Vasya and Multisets

    传送门 [http://codeforces.com/contest/1051/problem/C] 题意 给你一堆数,问是否可以分为两堆使得两堆里只出现一下的数字的种类相等,可以输出任意一种分的方式 ...

  4. 个人项目Week1

    一.项目时间规划与实际用时 PSP2.1 Personal Software Process Stages 预计时间/h 实际时间/h Planning 计划     · Estimate · 估计这 ...

  5. Scapy的使用

    0.前言 最近现场测试项目时,突如其来需要伪造IGMP报文,骗取交换机相关组播流量,慌忙之下学习了Scapy的使用,以及相关快速学习的方法,在这里分享下. 1.Scapy库安装 github地址:ht ...

  6. Java abstract interface与 interface的区别

    我们常常遇到abstract class与 interface的区别,今天却遇到了abstract interface,感觉interface不用abstract再修饰了啊.结论:事实也确实如此,编译 ...

  7. [转帖]浅析java程序的执行过程

    浅析java程序的执行过程 转帖来源: https://www.cnblogs.com/wangjiming/p/10315983.html 之前学习过 这一块东西 但是感觉理解的不深刻. copy一 ...

  8. Laravel 常见错误 1071 Specified key was too long

    Laravel 5.5 + Mysql 5.5 ,执行 migrate 时,提示索引长度超过指定的 1000 bytes 原因: Mysql 对索引有一定的长度限制,版本不同长度不同: MyIsAm ...

  9. Oracle面试题(基础篇)

    1. Oracle跟SQL Server 2005的区别? 宏观上: 1). 最大的区别在于平台,oracle可以运行在不同的平台上,sql server只能运行在windows平台上,由于windo ...

  10. php常用扩展安装

    ####memcache wget http://pecl.php.net/get/memcache-2.2.7.tgztar xf memcache-2.2.7.tgz cd memcache-2. ...