初见安~这里是传送门:洛谷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]紧急集合 / 聚会相关推荐

  1. 洛谷 P4281 [AHOI2008]紧急集合 / 聚会(树上倍增 LCA)

    [AHOI2008]紧急集合 / 聚会 题目描述 欢乐岛上有个非常好玩的游戏,叫做"紧急集合".在岛上分散有 n n n 个等待点,有 n − 1 n-1 n−1 条道路连接着它们 ...

  2. P4281 [AHOI2008]紧急集合 / 聚会

    P4281 [AHOI2008]紧急集合 / 聚会 军训完.发现我自己连lca版都不会了 然后就强行写了这个题 然后卡了两天的原因就是计算距离写错了 #include<cstdio> #i ...

  3. 洛谷 P1293 班级聚会

    P1293 班级聚会 题目描述 毕业25年以后,我们的主人公开始准备同学聚会.打了无数电话后他终于搞到了所有同学的地址.他们有些人仍在本城市,但大多数人分散在其他的城市.不过,他发现一个巧合,所有地址 ...

  4. P4281 [AHOI2008]紧急集合 / 聚会(LCA做法)

    题目描述 欢乐岛上有个非常好玩的游戏,叫做"紧急集合".在岛上分散有N个等待点,有N-1条道路连接着它们,每一条道路都连接某两个等待点,且通过这些道路可以走遍所有的等待点,通过道路 ...

  5. 题解【[AHOI2008]紧急集合 / 聚会】

    简化版题目: 有一棵 N N N个节点的树,和 Q Q Q组询问 有三个人分别在点 x , y , z x,y,z x,y,z现在希望你找到一个点,使得 三个人到这个点的距离和最小. 题目分析 首先, ...

  6. 洛谷3964 松鼠聚会

    题目地址 p3964 解题思路 首先学习一下曼哈顿距离和切比雪夫距离即二者之间的转换. 那根据切比雪夫距离的定义,只要x, y这个点到它周围八个点的距离都是一的话,就是使用的切比雪夫距离. 对于给出的 ...

  7. 洛谷 P3964 松鼠聚会

    题目链接 参考链接 题解: 这道题目的距离其实就是切比雪夫距离,又称棋盘距离,也就是D=max(∣x2−x1∣,∣y2−y1∣)D = max(|x_2-x_1|,|y_2-y_1|)D=max(∣x ...

  8. 洛谷P3964松鼠聚会

    题目 题意:求最小的从某一个点到其余点的切比雪夫距离和. 将一个图中的\((x,y)\)坐标转到新坐标\((x+y,x-y)\)后,图中的曼哈顿距离就是新图中的切比雪夫距离, 证明:分类讨论, 1.\ ...

  9. #距离#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​, ...

最新文章

  1. 7、Power Map—实例:添加二维数据表以及批注
  2. Flink SQL的N way join
  3. python代码的层次结构_Python的object和type理解及主要对象层次结构
  4. php 数组任意位置插入值
  5. 利用wxWindows开发界面程序
  6. Excel VBA使用总结
  7. 心心念念的安卓简单和多功能计算器来了
  8. Labview双通道虚拟示波器完整程序 实现功能如下图
  9. Jpg格式如何变成gif动图?仅需三步快速合成gif
  10. 菜鸟学R语言(组间多重比较)
  11. Android使用SubsamplingScaleImageView完美查看超大图片
  12. 解决插件在IE增强保护模式下无法运行的问题
  13. 一个三流学校程序员的奋斗!(转)
  14. MarkdownPad 2的安装、配置、优化,自定义样式、生成目录,解决win10渲染错误等
  15. 工作多年,对程序员“未来”的一些看法
  16. IDEA中DEBUG时断点变成灰色
  17. HTML5期末大作业:美妆网页主题网站设计——清新的手工肥皂网站展示(4页)HTML+CSS+JavaScript
  18. Visual Saliency Transformer 读后感
  19. 【研发管理】三手项目 接盘时 必须要做的四件事
  20. C++ Reference: Standard C++ Library reference: C Library: cmath: erfc

热门文章

  1. git clone 只有.git文件夹 git status后发现文件夹全都被删除了
  2. 精准数据采集是什么?
  3. android加入图片命名规则
  4. 爱因斯坦为什么那么牛,看看大家怎么说?
  5. Jquery 动画效果 左右移动
  6. 【FAQ】软件保护系统Themida常见问题集锦(一)—Themida和WinLicense有什么区别?
  7. 鸭子的应聘 我是学c 的
  8. 自己安装黑苹果的心酸路程。
  9. 关于我是如何自学Java,一个自学网站推荐How2j
  10. MPEG音频编码及分析