洛谷· [AHOI2008]紧急集合 / 聚会
初见安~这里是传送门:洛谷P4281紧急集合/聚会
题目描述
欢乐岛上有个非常好玩的游戏,叫做“紧急集合”。在岛上分散有N个等待点,有N-1条道路连接着它们,每一条道路都连接某两个等待点,且通过这些道路可以走遍所有的等待点,通过道路从一个点到另一个点要花费一个游戏币。
参加游戏的人三人一组,开始的时候,所有人员均任意分散在各个等待点上(每个点同时允许多个人等待),每个人均带有足够多的游戏币(用于支付使用道路的花费)、地图(标明等待点之间道路连接的情况)以及对话机(用于和同组的成员联系)。当集合号吹响后,每组成员之间迅速联系,了解到自己组所有成员所在的等待点后,迅速在N个等待点中确定一个集结点,组内所有成员将在该集合点集合,集合所用花费最少的组将是游戏的赢家。
小可可和他的朋友邀请你一起参加这个游戏,由你来选择集合点,聪明的你能够完成这个任务,帮助小可可赢得游戏吗?
输入格式:
第一行两个正整数N和M(N<=500000,M<=500000),之间用一个空格隔开。分别表示等待点的个数(等待点也从1到N进行编号)和获奖所需要完成集合的次数。 随后有N-1行,每行用两个正整数A和B,之间用一个空格隔开,表示编号为A和编号为B的等待点之间有一条路。 接着还有M行,每行用三个正整数表示某次集合前小可可、小可可的朋友以及你所在等待点的编号。
输出格式:
一共有M行,每行两个数P,C,用一个空格隔开。其中第i行表示第i次集合点选择在编号为P的等待点,集合总共的花费是C个游戏币。
输入样例#1:
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:
5 2
2 5
4 1
6 0
说明
40%的数据中N<=2000,M<=2000
100%的数据中,N<=500000,M<=500000
题解
一开始还以为直接3个点求LCA(最近公共祖先)【传送门建设中】然后求路径就过去了。结果……连样例都过不了。
为什么不能直接3个点一起求LCA,因为我们看样例就可以发现一件事情:
点4、5、6集合时,最近的方案当然是都到点5去,但是直接求3个点的LCA的话答案一定是在点4集合。
那么我们怎么把5搞出来呢——很明显,5是5和6的LCA。4需要做的就是过来集合就行了。所以我们可以3次两两求LCA——求出来过后求剩下那个点到这个公共祖先的距离,作比较,得到最小的一个,就行了。
思路很简单,细节有点复杂,略显暴力。但是还是可以的。
当然为了力求LCA快一些,本人用了树链剖分来求LCA。会特别注释一下的。
上代码及详解——
#include<bits/stdc++.h>
#define maxn 500005
using namespace std;
int n, m;
struct edge
{int to, nxt;edge(){}edge(int tt, int nn){to = tt, nxt = nn;}
}e[maxn << 1];int head[maxn], k = 0;
void add(int u, int v)
{e[k] = edge(v, head[u]);head[u] = k++;
}int dep[maxn], size[maxn], son[maxn], fa[maxn];
void dfs_getson(int u)//树剖初始化1
{size[u] = 1;int v;for(int i = head[u]; ~i; i = e[i].nxt){v = e[i].to;if(v == fa[u]) continue;dep[v] = dep[u] + 1;fa[v] = u;dfs_getson(v);size[u] += size[v];if(size[v] > size[son[u]]) son[u] = v;}
}int top[maxn];
void dfs_rewrite(int u, int tp)//树剖初始化2
{top[u] = tp;int v;if(son[u]) dfs_rewrite(son[u], tp);for(int i = head[u]; ~i; i = e[i].nxt){v = e[i].to;if(v != fa[u] && v != son[u]) dfs_rewrite(v, v);}
}struct node//为了方便处理答案开的结构体
{int x, ans;node(){}node(int xx, int aa){x = xx, ans = aa;}
};node ask1(int u, int v)//树剖求解LCA和路径(不用在意那个1,之前想复杂了就有个ask2
{int ans = 0;while(top[u] != top[v]){if(dep[top[u]] > dep[top[v]]) swap(u, v);ans += dep[v] - dep[fa[top[v]]];v = fa[top[v]];}if(dep[u] > dep[v]) swap(u, v);ans += dep[v] - dep[u];return node(u, ans);
}int main()
{memset(head, -1, sizeof head);scanf("%d%d", &n, &m);int u, v, w;for(int i = 1; i < n; i++){scanf("%d%d", &u, &v);add(u, v);add(v, u);}dfs_getson(1);dfs_rewrite(1, 1);while(m--){scanf("%d%d%d", &u, &v, &w);node tmp1, ans = node(0, 0x3f3f3f3f), tmp2;//三次分别LCAtmp1 = ask1(u, v);tmp2 = ask1(tmp1.x, w);if(tmp1.ans + tmp2.ans < ans.ans) ans = node(tmp1.x, tmp1.ans + tmp2.ans);tmp1 = ask1(v, w);tmp2 = ask1(tmp1.x, u);if(tmp1.ans + tmp2.ans < ans.ans) ans = node(tmp1.x, tmp1.ans + tmp2.ans);tmp1 = ask1(u, w);tmp2 = ask1(tmp1.x, v);if(tmp1.ans + tmp2.ans < ans.ans) ans = node(tmp1.x, tmp1.ans + tmp2.ans);printf("%d %d\n", ans.x, ans.ans);}return 0;
}
/*
10 1
1 2
1 3
1 10
2 4
2 5
2 6
3 7
7 8
7 9
4 6 10
这是自己当时查错时的数据QwQ然后就想到了暴力LCA 3次
*/
迎评:)
——End——
洛谷· [AHOI2008]紧急集合 / 聚会相关推荐
- 洛谷 P4281 [AHOI2008]紧急集合 / 聚会(树上倍增 LCA)
[AHOI2008]紧急集合 / 聚会 题目描述 欢乐岛上有个非常好玩的游戏,叫做"紧急集合".在岛上分散有 n n n 个等待点,有 n − 1 n-1 n−1 条道路连接着它们 ...
- P4281 [AHOI2008]紧急集合 / 聚会
P4281 [AHOI2008]紧急集合 / 聚会 军训完.发现我自己连lca版都不会了 然后就强行写了这个题 然后卡了两天的原因就是计算距离写错了 #include<cstdio> #i ...
- 洛谷 P1293 班级聚会
P1293 班级聚会 题目描述 毕业25年以后,我们的主人公开始准备同学聚会.打了无数电话后他终于搞到了所有同学的地址.他们有些人仍在本城市,但大多数人分散在其他的城市.不过,他发现一个巧合,所有地址 ...
- P4281 [AHOI2008]紧急集合 / 聚会(LCA做法)
题目描述 欢乐岛上有个非常好玩的游戏,叫做"紧急集合".在岛上分散有N个等待点,有N-1条道路连接着它们,每一条道路都连接某两个等待点,且通过这些道路可以走遍所有的等待点,通过道路 ...
- 题解【[AHOI2008]紧急集合 / 聚会】
简化版题目: 有一棵 N N N个节点的树,和 Q Q Q组询问 有三个人分别在点 x , y , z x,y,z x,y,z现在希望你找到一个点,使得 三个人到这个点的距离和最小. 题目分析 首先, ...
- 洛谷3964 松鼠聚会
题目地址 p3964 解题思路 首先学习一下曼哈顿距离和切比雪夫距离即二者之间的转换. 那根据切比雪夫距离的定义,只要x, y这个点到它周围八个点的距离都是一的话,就是使用的切比雪夫距离. 对于给出的 ...
- 洛谷 P3964 松鼠聚会
题目链接 参考链接 题解: 这道题目的距离其实就是切比雪夫距离,又称棋盘距离,也就是D=max(∣x2−x1∣,∣y2−y1∣)D = max(|x_2-x_1|,|y_2-y_1|)D=max(∣x ...
- 洛谷P3964松鼠聚会
题目 题意:求最小的从某一个点到其余点的切比雪夫距离和. 将一个图中的\((x,y)\)坐标转到新坐标\((x+y,x-y)\)后,图中的曼哈顿距离就是新图中的切比雪夫距离, 证明:分类讨论, 1.\ ...
- #距离#JZOJ 3256 BZOJ 3170 洛谷 3964 松鼠聚会
题目 分析 首先这个距离是切比雪夫距离,得把它转换成曼哈顿距离,也就是把(x,y)(x,y)(x,y)变成(x+y2,x−y2)(\frac{x+y}{2},\frac{x-y}{2})(2x+y, ...
最新文章
- 7、Power Map—实例:添加二维数据表以及批注
- Flink SQL的N way join
- python代码的层次结构_Python的object和type理解及主要对象层次结构
- php 数组任意位置插入值
- 利用wxWindows开发界面程序
- Excel VBA使用总结
- 心心念念的安卓简单和多功能计算器来了
- Labview双通道虚拟示波器完整程序 实现功能如下图
- Jpg格式如何变成gif动图?仅需三步快速合成gif
- 菜鸟学R语言(组间多重比较)
- Android使用SubsamplingScaleImageView完美查看超大图片
- 解决插件在IE增强保护模式下无法运行的问题
- 一个三流学校程序员的奋斗!(转)
- MarkdownPad 2的安装、配置、优化,自定义样式、生成目录,解决win10渲染错误等
- 工作多年,对程序员“未来”的一些看法
- IDEA中DEBUG时断点变成灰色
- HTML5期末大作业:美妆网页主题网站设计——清新的手工肥皂网站展示(4页)HTML+CSS+JavaScript
- Visual Saliency Transformer 读后感
- 【研发管理】三手项目 接盘时 必须要做的四件事
- C++ Reference: Standard C++ Library reference: C Library: cmath: erfc