BZOJ1787 [Ahoi2008]Meet 紧急集合 【LCA】
来源:互联网 发布:imap4 端口 编辑:程序博客网 时间:2024/05/29 15:41
1787: [Ahoi2008]Meet 紧急集合
Time Limit: 20 Sec Memory Limit: 162 MBSubmit: 3578 Solved: 1635
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
6 4
1 2
2 3
2 4
4 5
5 6
4 5 6
6 3 1
2 4 4
6 6 6
1 2
2 3
2 4
4 5
5 6
4 5 6
6 3 1
2 4 4
6 6 6
Sample Output
5 2
2 5
4 1
6 0
HINT
点很少,只有三个,画一下图,手动模拟一下就会发现:我们要求的就是画一条线将三个点连起来,使线最短
由于树路径的唯一性,连接三个点的路径是唯一的,但是由于走法的不同会导致因为重复部分路径而使路径增长
未使路径最短,我们就不能走复路,所以我们只需求出三者最大的LCA,再将另外一个点走上LCA所在路径就好了
如图:
具体LCA用倍增实现,复杂度O(mlogn + nlogn),一个是预处理,一个是询问
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#define LL long long int#define REP(i,n) for (int i = 1; i <= (n); i++)#define Redge(u) for (int k = head[u]; k != -1; k = edge[k].next)using namespace std;const int maxn = 500005,maxm = 1000005,INF = 1000000000;inline int RD(){int out = 0,flag = 1; char c = getchar();while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}while (c >= 48 && c <= 57) {out = (out << 1) + (out << 3) + c - '0'; c = getchar();}return out * flag;}int dep[maxn],fa[maxn][20];int N,M,head[maxn],nedge = 0,p[4];struct node{int lca,u,v;}e[4];struct EDGE{int to,next;}edge[maxm];inline void build(int u,int v){edge[nedge] = (EDGE){v,head[u]}; head[u] = nedge++;edge[nedge] = (EDGE){u,head[v]}; head[v] = nedge++;}void dfs(int u,int f,int d){dep[u] = ++d; fa[u][0] = f;Redge(u) if (edge[k].to != f) dfs(edge[k].to,u,d);}void init(){REP(j,19) REP(i,N) fa[i][j] = fa[fa[i][j - 1]][j - 1];}int LCA(int u,int v){if (dep[u] < dep[v]) u ^= v ^= u ^= v;int d = dep[u] - dep[v];for (int i = 0; (1 << i) <= d; i++)if ((1 << i) & d) u = fa[u][i];if (u == v) return u;for (int i = 19; i >= 0; i--)if (fa[u][i] != fa[v][i]) u = fa[u][i],v = fa[v][i];return fa[u][0];}void B_Sort(){for (int i = 1; i <= 3; i++)for (int j = i + 1; j <= 3; j++)if (dep[e[i].lca] > dep[e[j].lca]) swap(e[i],e[j]);}void solve(){int ans,u;while (M--){REP(i,3) p[i] = RD();for (int i = 1,k = 0; i < 3; i++)for (int j = i + 1; j <= 3; j++)e[++k].u = i,e[k].v = j,e[k].lca = LCA(p[i],p[j]);B_Sort();//REP(i,3) printf("%d and %d lca: %d\n",e[i].u,e[i].v,e[i].lca);REP(i,3) if (i != e[1].u && i != e[1].v) {u = p[i];break;}ans = dep[p[e[1].u]] + dep[p[e[1].v]] + dep[u] - 2 * dep[e[1].lca] - dep[e[3].lca];printf("%d %d\n",e[3].lca,ans);}}int main(){memset(head,-1,sizeof(head));N = RD(); M = RD();REP(i,N - 1) build(RD(),RD());dfs(1,0,0); init();solve();return 0;}
阅读全文
0 0
- 【Ahoi2008】【lca】【bzoj1787】Meet 紧急集合
- [BZOJ1787][AHOI2008]Meet 紧急集合(LCA)
- BZOJ1787: [Ahoi2008]Meet 紧急集合(LCA)
- [bzoj1787][Ahoi2008]Meet 紧急集合 倍增LCA
- BZOJ1787 [Ahoi2008]Meet 紧急集合 【LCA】
- [BZOJ1787][Ahoi2008]Meet 紧急集合
- bzoj1787 [Ahoi2008]Meet 紧急集合
- BZOJ1787 [Ahoi2008]Meet 紧急集合
- bzoj1787 [Ahoi2008]Meet 紧急集合
- BZOJ1787: [Ahoi2008]Meet 紧急集合
- [BZOJ1787][Ahoi2008]Meet 紧急集合
- 【BZOJ1787】【Ahoi2008】Meet 紧急集合 LCA、双倍经验
- [BZOJ1787]AHOI2008 紧急集合|LCA
- 11.30 bzoj1787 [Ahoi2008]Meet 紧急集合
- bzoj1787 [Ahoi2008]Meet 紧急集合 树上倍增
- [BZOJ1787][Ahoi2008]Meet 紧急集合&&[BZOJ1832][AHOI2008]聚会
- [bzoj1787][Ahoi2008]Meet 紧急集合&&[bzoj1832][AHOI2008]聚会
- BZOJ1787: [Ahoi2008]Meet 紧急集合&1832: [AHOI2008]聚会
- sql语句时间格式和查找某一段时间内有变化的
- 计算机网络原理第一章学习总结
- NeHe tutorial 课程列表
- 笔记
- ACM PKU 题目分类(完整整理版本)
- BZOJ1787 [Ahoi2008]Meet 紧急集合 【LCA】
- 服务器-Nginx配置
- WPF 项目中遇到的问题
- 2017-12-09 杭电OJ2003 《求绝对值》
- react中将数据存放在缓存中的方法和将数据从缓存中取出的方法
- maven聚合与继承
- 图论4
- 传苹果供应商开造AR眼镜 广州妇儿配AI医生能看32种病
- 赠票福利!英伟达人工智能大讲堂上海站开始报名了!