热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

bzoj1787&&bzoj1832:[Ahoi2008]Meet紧急集合(倍增LCA)算法竞赛进阶指南

题目描述原题连接Y岛风景美丽宜人,气候温和,物产丰富。Y岛上有N个城市(编号$1,2,…,N$),有$N1$条城市间的道路连接着它们。每一条道路都连接某两个城市。幸运的是,小可可通

题目描述

原题连接

Y岛风景美丽宜人,气候温和,物产丰富。

Y岛上有N个城市(编号\(1,2,…,N\)),有\(N-1\)条城市间的道路连接着它们。

每一条道路都连接某两个城市。

幸运的是,小可可通过这些道路可以走遍Y岛的所有城市。

神奇的是,乘车经过每条道路所需要的费用都是一样的。

小可可,小卡卡和小YY经常想聚会,每次聚会,他们都会选择一个城市,使得3个人到达这个城市的总费用最小。

由于他们计划中还会有很多次聚会,每次都选择一个地点是很烦人的事情,所以他们决定把这件事情交给你来完成。

他们会提供给你地图以及若干次聚会前他们所处的位置,希望你为他们的每一次聚会选择一个合适的地点。

输入格式

第一行两个正整数,\(N\)\(M\),分别表示城市个数和聚会次数。

后面有\(N-1\)行,每行用两个正整数\(A\)\(B\)表示编号为\(A\)和编号为\(B\)的城市之间有一条路。

再后面有\(M\)行,每行用三个正整数表示一次聚会的情况:小可可所在的城市编号,小卡卡所在的城市编号以及小YY所在的城市编号。

输出格式

一共有\(M\)行,每行两个数\(Pos\)\(Cost\),用一个空格隔开,表示第\(i\)次聚会的地点选择在编号为\(Pos\)的城市,总共的费用是经过\(Cost\)条道路所花费的费用。

数据范围

\[ N \le 500000 \\\M \le 500000 \\\\]

输入样例:

6 4
1 2
2 3
2 4
4 5
5 6
4 5 6
6 3 1
2 4 4
6 6 6

输出样例:

5 2
2 5
4 1
6 0

解题报告

题意理解

不同于一般的LCA题目,这道题目是,在一棵\(n-1\)条边的树上,有三个节点,要你求出这个三个点抵达一个汇聚点最少代价.


算法解析

这道题目的核心点,就是它是由三个点构成的最短路.

为什么,它同于一般的题目,难道不是让我们直接求出三个点的最近公共祖先?

汇聚点为什么不是
\[ Lca(Lca(a,b),Lca(a,c)) \\\或者 \\\Lca(Lca(a,c),Lca(b,c)) \\\以上选项二选一 \]
如果你真的是这么想,脑海里面只有A,B选项,那么你应该庆幸,出题人比较良心丧心病狂留下的唯一良知,他给你提出了一个样例,告诉你为什么不是这样.

因为文化课考试的时候,题目都是A,B,C或者再来一个D的单项选择题.

技术图片

\(3\)人分别在\(4,5,6\)三个节点上面.

仔仔细细地观察一下,我们发现这道题目的汇聚点,应该是5,而不是4.

  1. 假如说我们按照楼上这个错误思路,我们的三点的最近公共祖先节点,应该是4.

  2. 但是最少花费,显然是在\(5\)号节点.

我们的思路居然是错误的!!!

它到底错误在了哪里.

我们要分析一下,这道题目,为什么选择的是5,而不是4?

选择\(4\),那么\(1\)号小朋友不需要行动.

选择\(5\),那么\(2,3\)号小朋友不需要行动.


我们可以这么现实化这道题目.

\(2,3\)号小朋友他们是互相的知己一对狗男女,所以说,他们想要在一起.发朋友圈,秀恩爱

所以\(2,3\)号小朋友他们会先聚集在一起

花费代价为
\[ 消耗距离=deep[b]+deep[c]-deep[Lca(b,c)] \]

技术图片

此时我们面临两大选择.

  1. \(1\)号同学孤身一人走到2,3号同学相遇的地方.
  2. \(2,3\)号同学一起手拉手\(1\)号同学相遇.再秀一次恩爱,虐一下单身狗1号

假如说\(1\)号同学,与\(2,3\)号同学相隔\(L\)个距离.

我们将会发现,两大选择,会产生两大代价.

方案一
\[ 消耗距离=L-deep[Lca(a,Lca(b,c))] \]
方案二
\[ 消耗距离=2*L-deep[Lca(a,Lca(b,c))] \]
那么显然我们发现第一个方案是最优秀的方案.

所以说我们得出了性质,那就是.
\[ { } 消耗距离=deep[b]+deep[c]-2 \times deep[Lca(b,c)] +L-deep[Lca(a,Lca(b,c))] \\\其中L=deep[a] \]
综上所述,同理其他两种方案也可以得出.

  1. \(1,2\)先在一起
  2. \(2,3\)先在一起
  3. \(1,3\)先在一起

代码解析

#include 
using namespace std;
const int N=500000+200,M=500000*2+100;
int n,m,s,lg[N],deep[N];
struct Lca
{
    int head[M],Next[M],edge[M],tot,fa[N][22];
    void init()
    {
        memset(head,0,sizeof(head));
        tot=0;
    }
    void add_edge(int a,int b)
    {
        edge[++tot]=b;
        Next[tot]=head[a];
        head[a]=tot;
        return ;
    }
    void dfs(int x,int y)
    {
        deep[x]=deep[y]+1;
        fa[x][0]=y;
        for(int i=1; (1<deep[y])
            x=fa[x][lg[deep[x]-deep[y]]-1];
        if (x==y)
            return x;
        for(int k=lg[deep[x]]; k>=0; k--)
            if (fa[x][k]!=fa[y][k])
            {
                x=fa[x][k];
                y=fa[y][k];
            }
        return fa[x][0];
    }
} g1;
int main()
{
    scanf("%d%d",&n,&m);
    g1.init();
    for(int i=1; idy) 
            dx=dy,c_x=c_y;
        if(dx>dz) 
            dx=dz,c_x=c_z;
        printf("%d %d\n",c_x,dx);
    }
    return 0;
}

bzoj 1787 && bzoj 1832: [Ahoi2008]Meet 紧急集合(倍增LCA)算法竞赛进阶指南


推荐阅读
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 本文内容为asp.net微信公众平台开发的目录汇总,包括数据库设计、多层架构框架搭建和入口实现、微信消息封装及反射赋值、关注事件、用户记录、回复文本消息、图文消息、服务搭建(接入)、自定义菜单等。同时提供了示例代码和相关的后台管理功能。内容涵盖了多个方面,适合综合运用。 ... [详细]
  • 本文讲述了作者通过点火测试男友的性格和承受能力,以考验婚姻问题。作者故意不安慰男友并再次点火,观察他的反应。这个行为是善意的玩人,旨在了解男友的性格和避免婚姻问题。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
author-avatar
郑小斌-杭州
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有