【LCA】BZOJ1832 & BZOJ1787(AHOI)-集会
【题目大意】
一个图有n个点n-1条边(也就是说是一棵树),求其中三点共同到达某一点经过总共的最少边数以及共同到达的那一点。
【思路】
借用一下黄学长给的结论:三个点两两取LCA,其中必有两个相同,则另外一个点就是答案。
注意BZOJ大数据要用scanf和printf,因为cout的原因RE了好几次_(:зゝ∠)_基本算是一道标程类的题目了啦。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
const int MAXN=;
const int M=;
using namespace std;
int n,m;
vector<int> G[MAXN];
int fa[MAXN][M];
int dep[MAXN]; void dfs(int v,int p,int d)
{
fa[v][]=p;
dep[v]=d;
for (int i=;i<G[v].size();i++)
if (G[v][i]!=p) dfs(G[v][i],v,d+);
} void kb()
{
for (int i=;i<M;i++)
for (int j=;j<=n;j++)
{
fa[j][i]=fa[fa[j][i-]][i-];
}
} void init()
{
scanf("%d%d",&n,&m);
for (int i=;i<n-;i++)
{
int fr,to;
scanf("%d%d",&fr,&to);
G[fr].push_back(to);
G[to].push_back(fr);
}
dfs(,,);
kb();
} int swim(int x,int H)
{
for (int i=;H>;i++)
{
if (H&) x=fa[x][i];
H/=;
}
return x;
} int LCA(int u,int v)
{
if (dep[u]<dep[v]) swap(u,v);
u=swim(u,dep[u]-dep[v]);
if (u==v) return u;
for (int i=M-;i>=;i--)
{
if (fa[u][i]!=fa[v][i])
{
u=fa[u][i];
v=fa[v][i];
}
}
return fa[u][];
} int dis(int x,int y)
{
int z=LCA(x,y);
int re=dep[x]+dep[y]-*dep[z];
return re;
} void query()
{
int u,v,w;
for (int i=;i<m;i++)
{
scanf("%d%d%d",&u,&v,&w);
int uv=LCA(u,v);
int uw=LCA(u,w);
int vw=LCA(v,w);
int pos;
if (uv==uw) pos=vw;
else if (uv==vw) pos=uw;
else pos=uv;
int cost=dis(u,pos)+dis(v,pos)+dis(w,pos);
printf("%d %d\n",pos,cost);
}
} int main()
{
init();
query();
return ;
}
【LCA】BZOJ1832 & BZOJ1787(AHOI)-集会的更多相关文章
- LCA 【bzoj1787】[Ahoi2008]Meet 紧急集合
LCA [bzoj1787][Ahoi2008]Meet 紧急集合 题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1787 注意到边权为一 ...
- 【块状树】【LCA】bzoj1787 [Ahoi2008]Meet 紧急集合
分块LCA什么的,意外地快呢…… 就是对询问的3个点两两求LCA,若其中两组LCA相等,则答案为第三者. 然后用深度减一减什么的就求出距离了. #include<cstdio> #incl ...
- 【bzoj1787】&【bzoj1832】[Ahoi2008]Meet 紧急集合 & 聚会
bzoj1787就是bzoj1832 bzoj1832 空间和时间少了一些... 求三个结点到一个结点距离之和最小的结点以及距离和 求出两两lca,其中有两个相同,答案则为另一个 感觉就是一大暴力.. ...
- bzoj1787[Ahoi2008]Meet 紧急集合&bzoj1832[AHOI2008]聚会
bzoj1787[Ahoi2008]Meet 紧急集合 bzoj1832[AHOI2008]聚会 题意: 给个树,每次给三个点,求与这三个点距离最小的点. 题解: 倍增求出两两之间的LCA后,比较容易 ...
- BZOJ1787 [Ahoi2008]Meet 紧急集合 LCA
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1787 题意概括 有一棵节点为n个(n≤500000)的树.接下来m次询问(m≤500000),每次 ...
- 【BZOJ1787】[Ahoi2008]Meet 紧急集合 LCA
[BZOJ1787][Ahoi2008]Meet 紧急集合 Description Input Output Sample Input 6 4 1 2 2 3 2 4 4 5 5 6 4 5 6 6 ...
- [BZOJ1602&BZOJ1787&BZOJ2144]树上LCA的算法巩固练习
简述求LCA的倍增算法 对于树上的所有节点,我们可以很轻松地通过dfs求出其直接的父亲节点以及其深度 通过类似RMQ的原理我们可以处理出每个节点的第2^i个父亲 //这个过程既可以在dfs之后双重循环 ...
- 【BZOJ-1787&1832】Meet紧急集合&聚会 倍增LCA
1787: [Ahoi2008]Meet 紧急集合 Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 2259 Solved: 1023[Submit] ...
- bzoj1832: [AHOI2008]聚会--LCA
本来觉得这是一道挺水的题目,后来觉得出题人挺变态的= = 半个小时敲完后,内存超限它给我看TLE,还是0ms,后来才发现内存限制64m 然后卡了一个小时后AC了.. 题目大意是在一棵树上找三点的最短路 ...
随机推荐
- div圆角
div{ -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius: 10px;}
- bzoj 1197 DP
我们可以将这个问题转化为在n维空间中一共放m个n维球,求这m个球最多将这个空间分为不同的几个部分. 那么我们设w[i][j]代表i为空间放j个球分为的部分,那么w[i][j]=w[i][j-1]+w[ ...
- Linux内核堆栈使用方法 进程0和进程1【转】
转自:http://blog.csdn.net/yihaolovem/article/details/37119971 目录(?)[-] 8 Linux 系统中堆栈的使用方法 81 初始化阶段 82 ...
- Jmeter获取当前时间、历史时间、未来时间的方式
__time : 获取时间戳.格式化时间 操作步骤: 1.通过函数助手,生成一个_time 函数: 2.如果参数为时间戳,那公式为: ${__time(,)} : 默认该公式精确到毫秒级别, 13 ...
- 改变ASPxpivotgridview弹出的prefilter的标题
说是要给变标题,再网上找了很久的资料,基本上属于一无所获,后来在官网上看到一个技术支持用vb写的,说是要本地化什么的,个人技术有限不是太懂 后来干脆就直接注册个账号,发问了,好歹等到了晚上十点左右,有 ...
- Centos7 配置网络
/* Centos7 的网络 不可以用ifconfig获取,需要安装包 所以 .*/ //查看ip [root@master ~]# ip a /* Centos7 的网卡名字与 Centos6有区别 ...
- Keepalived高可用配置
Keepalived简介 Keepalived基于VRRP协议在服务器之间建立了主备关系,通常称之为高可用对.VRRP中文叫虚拟路由冗余协议,目的是解决静态路由的单点故障问题.高可用对之间通过IP多播 ...
- ASP .NET CORE 部署linux 系统上的所需要的sdk 使用链接
https://www.microsoft.com/net/learn/get-started/linuxopensuse
- [PAT] 1142 Maximal Clique(25 分)
1142 Maximal Clique(25 分) A clique is a subset of vertices of an undirected graph such that every tw ...
- hdu 2044-2050 递推专题
总结一下做递推题的经验,一般都开成long long (别看项数少,随便就超了) 一般从第 i 项开始推其与前面项的关系(动态规划也是这样),而不是从第i 项推其与后面的项的关系. hdu2044:h ...