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过程中求出离根的距离.把每次询问的三个点两两求出最短距离,这样最终 ...
随机推荐
- Spring RPC 入门学习(3)-插入Student对象
Spring RPC 向后台传递对象 1. 新建RPC接口:StudentInterface.java package com.cvicse.ump.rpc.interfaceDefine; impo ...
- linux-安装-源码安装
编译安装 tengine
- C++ string简单的使用技巧
截取substr //string的操作 #include<iostream> using namespace std; int main() { string a,b; a=" ...
- 705 B. Spider Man
传送门 [http://codeforces.com/contest/705/problem/B] 题意 这题意看原文的真tm难懂Woc,但结合样例就知道大概意思了 两个轮流分环,可以这么理解两个人轮 ...
- 【2016.3.16】作业 VS2015安装&单元测试(1)
首先说下本机配置. CPU:Intel Atom x5-z8300 @1.44GHz 内存:2GB 操作系统:Windows10 家庭版 32位 硬盘:32GB 然后开始怒装visual studio ...
- 四则运算coding
https://coding.net/u/ztf1641429293/p/sizeyunshuan/git/blob/master/Sizenyunsuan.java
- Individual Project - Word frequency program——12061154Joy
Description&Requirement: http://www.cnblogs.com/jiel/p/3978727.html 项目时间估计 理解项目要求: 1h 构建项目逻辑: 1h ...
- “Linux内核分析”实验报告
Linux内核分析:实验一 潘俊洋 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-100002900 ...
- 使用matlab自带工具实现rcnn
平台:matlab2016b matlab自带一个cifar10Net工具可用于深度学习. 图片标注 这里使用的是matlab自带的工具trainingImageLabeler对图像进行roi的标注. ...
- Maven的课堂笔记3
8 仓库管理 仓库可以分为三种:1.本地仓库(本机).2.私服(公司局域网内的maven服务器).3.中央仓库(互联上,例如 struts2官网,或者hibernate官网) 可以根据maven坐标定 ...