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

2019MultiUniversityTrainingContest31011Squrirrel——树形DP

Thisway题意:给你一棵树,路径上都有权值,你现在能将一条边权变为0,问你从某个节点出发到最远的叶子结点的路径最短是

This way

题意:

给你一棵树,路径上都有权值,你现在能将一条边权变为0,问你从某个节点出发到最远的叶子结点的路径最短是多少。

题解:

这道题乍一看不难,但是它的情况很多,所以debug了很久才过。首先我们处理出每个节点距离它子树的叶子结点的最远,第二远,第三远的距离,再用DP做出每个节点删掉一条边后到叶子结点最远,第二远的距离。之后再用一个dfs做答案,首先参数需要传:
1.从父亲传下来的,不包括这颗子树的最远未删边距离,2.从父亲传下来的,不包括这颗子树的最优最远删边距离。
那么这个节点的答案就是
min{max{父亲未删边,这棵树删边最大,这棵树未删边第二大},max{父亲删边最优最大,这棵树未删边最大}}
为什么,因为不确定删边最大和未删边第二大的关系,所以需要判一下。
先说一下重要数组的意义:
no_mx:表示未删边最大
no_smx:表示未删边第二大
del_mx:表示删边最大
no_:表示父亲传下来的未删边最大
del_:表示父亲传下来的删边最大
那么之后麻烦的就来了,首先对于他的某一个儿子节点,
1.如果他是这个点的未删边最大的儿子节点:
1.1如果他是这个点的删边最大儿子节点:
1.1.1他就会有no_smx,no_tmx,del_smx,del_tmx四种可以传下去的,那么我们肯定是删掉no_smx,那么也就是说在no_tmx和del_smx中选择最大的
1.2如果他是这个点的第二或者其它儿子节点:
1.2.1他就会有no_smx,no_tmx,del_mx,del_tmx四种可以传下去的,那么我们不知道删掉no_smx还是del_mx,那么我们就在这两个中取一个最小的,在之后与no_tmx取个最大的
2.如果他是这个节点的未删边第二:
2.1如果它是这个点的删边最大儿子节点:
2.1.1他就会有no_mx,no_tmx,del_mx,del_tmx,那么我们肯定是删掉no_mx,所以在del_smx与no_tmx中取个最大的
2.2如果它是这个节点的删边第二大儿子节点或者其它:
2.2.1它就会有no_mx,no_tmx,del_mx,del_tmx四种,那么我们删掉no_mx,所以在del_mx,与no_tmx中取个最大的
3.如果它是这个节点的未删边第三或者其它节点:
3.1如果它是这个点的删边最大儿子节点:
3.1.1它就会有no_mx,no_smx,del_smx,del_tmx四种,那么我们删掉no_mx,在no_smx,del_smx中取最大的
3.2如果它是这个点的删边第二或者其它儿子节点:
3.2.1它就会有no_mx,no_smx,del_mx,del_tmx四种,那么我们删掉no_mx,在no_smx,del_mx中取最大的

情况数有点多,令人绝望的代码。

#include
using namespace std;
const int N=2e6+5;
int dp[N][2],no_mx[N],no_smx[N],no_tmx[N],del_mx[N],del_smx[N],del_tmx[N],ans[N];
struct node
{int to,next,w;
}e[N*2];
int cnt,head[N];
void add(int x,int y,int w)
{e[cnt].to=y;e[cnt].next=head[x];e[cnt].w=w;head[x]=cnt++;
}
void dfs(int x,int fa)
{for(int i=head[x];~i;i=e[i].next){int ne=e[i].to,w=e[i].w;if(ne==fa)continue;dfs(ne,x);if(no_mx[ne]+w>no_mx[x])no_tmx[x]=no_smx[x],no_smx[x]=no_mx[x],no_mx[x]=no_mx[ne]+w;else if(no_mx[ne]+w>no_smx[x])no_tmx[x]=no_smx[x],no_smx[x]=no_mx[ne]+w;else if(no_mx[ne]+w>no_tmx[x])no_tmx[x]=no_mx[ne]+w;int d=min(dp[ne][1]+w,dp[ne][0]);dp[x][1]=min(max(dp[x][0],d),max(dp[x][1],dp[ne][0]+w));dp[x][0]=max(dp[x][0],dp[ne][0]+w);if(d>del_mx[x])del_tmx[x]=del_smx[x],del_smx[x]=del_mx[x],del_mx[x]=d;else if(d>del_smx[x])del_tmx[x]=del_smx[x],del_smx[x]=d;else if(d>del_tmx[x])del_tmx[x]=d;}
}
int p,val;
void fans(int x,int fa,int no_,int del_)
{ans[x]=min(max(no_,max(del_mx[x],no_smx[x])),max(del_,no_mx[x]));if(ans[x]x)p=x;for(int i=head[x];~i;i=e[i].next){int ne=e[i].to,w=e[i].w;if(ne==fa)continue;int nv=no_+w,nd;if(no_mx[ne]+w==no_mx[x]){nv=max(nv,no_smx[x]+w);nd=min(max(no_,no_smx[x]),max(del_+w,no_smx[x]+w));//去掉这条边,父亲传来的值if(min(dp[ne][1]+w,dp[ne][0])==del_mx[x])nd=min(nd,max(del_smx[x]+w,max(no_+w,no_tmx[x]+w)));//去掉其它儿子边elsend=min(nd,max(no_+w,max(no_tmx[x]+w,min(del_mx[x]+w,no_smx[x]+w))));}else if(no_mx[ne]+w==no_smx[x]){nv=max(nv,no_mx[x]+w);nd=min(max(no_,no_mx[x]),max(del_+w,no_mx[x]+w));if(min(dp[ne][1]+w,dp[ne][0])==del_mx[x])nd=min(nd,max(del_smx[x]+w,max(no_+w,no_tmx[x]+w)));elsend=min(nd,max(no_+w,max(no_tmx[x]+w,del_mx[x]+w)));}else{nv=max(nv,no_mx[x]+w);nd=min(max(no_,no_mx[x]),max(del_+w,no_mx[x]+w));if(min(dp[ne][1]+w,dp[ne][0])==del_mx[x])nd=min(nd,max(no_+w,max(no_smx[x]+w,del_smx[x]+w)));elsend=min(nd,max(no_+w,max(no_smx[x]+w,del_mx[x]+w)));}fans(ne,x,nv,nd);}
}
int main()
{//freopen("1.in","r",stdin);//freopen("out.txt","w",stdout);int t;scanf("%d",&t);while(t--){int n;scanf("%d",&n);memset(head,-1,sizeof(head));cnt&#61;0;val&#61;1e9;for(int i&#61;1;i<&#61;n;i&#43;&#43;)dp[i][0]&#61;dp[i][1]&#61;no_mx[i]&#61;no_smx[i]&#61;no_tmx[i]&#61;del_mx[i]&#61;del_smx[i]&#61;del_tmx[i]&#61;ans[i]&#61;0;int x,y,w;for(int i&#61;1;i}
/*
1
5
1 2 1
2 3 1
3 4 5
3 5 11
5
1 5 1
1 2 1
2 3 2
3 4 11
10
2 1 155
3 1 29
4 2 33
5 2 178
6 3 42
7 2 56
8 6 189
9 4 99
10 5 63
*/


推荐阅读
  • P2765魔术球问题这道题的思路实在是太罕见了,所以发一篇blog从某一新放入的球开始看起1.放入原来的柱子上2.放入新的柱子并将每个点进行拆点࿰ ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 本文介绍了一道经典的状态压缩题目——关灯问题2,并提供了解决该问题的算法思路。通过使用二进制表示灯的状态,并枚举所有可能的状态,可以求解出最少按按钮的次数,从而将所有灯关掉。本文还对状压和位运算进行了解释,并指出了该方法的适用性和局限性。 ... [详细]
  • Webpack5内置处理图片资源的配置方法
    本文介绍了在Webpack5中处理图片资源的配置方法。在Webpack4中,我们需要使用file-loader和url-loader来处理图片资源,但是在Webpack5中,这两个Loader的功能已经被内置到Webpack中,我们只需要简单配置即可实现图片资源的处理。本文还介绍了一些常用的配置方法,如匹配不同类型的图片文件、设置输出路径等。通过本文的学习,读者可以快速掌握Webpack5处理图片资源的方法。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • Go语言实现堆排序的详细教程
    本文主要介绍了Go语言实现堆排序的详细教程,包括大根堆的定义和完全二叉树的概念。通过图解和算法描述,详细介绍了堆排序的实现过程。堆排序是一种效率很高的排序算法,时间复杂度为O(nlgn)。阅读本文大约需要15分钟。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • This article discusses the efficiency of using char str[] and char *str and whether there is any reason to prefer one over the other. It explains the difference between the two and provides an example to illustrate their usage. ... [详细]
  • 本文由编程笔记#小编整理,主要介绍了关于数论相关的知识,包括数论的算法和百度百科的链接。文章还介绍了欧几里得算法、辗转相除法、gcd、lcm和扩展欧几里得算法的使用方法。此外,文章还提到了数论在求解不定方程、模线性方程和乘法逆元方面的应用。摘要长度:184字。 ... [详细]
  • 深入理解Java虚拟机的并发编程与性能优化
    本文主要介绍了Java内存模型与线程的相关概念,探讨了并发编程在服务端应用中的重要性。同时,介绍了Java语言和虚拟机提供的工具,帮助开发人员处理并发方面的问题,提高程序的并发能力和性能优化。文章指出,充分利用计算机处理器的能力和协调线程之间的并发操作是提高服务端程序性能的关键。 ... [详细]
  • 最大子序列和(maxsum)【问题描述】输入一个长度为n的整数序列(A1,A2,……,An),从中找出一段连续的长度不超过M的子序列,使得这个序列的和最大。例如:序列1,-3,5 ... [详细]
  • 796.[APIO2012]派遣在一个忍者的帮派里,一些忍者们被选中派遣给顾客,然后依据自己的工作获取报偿。在这个帮派里,有一名忍者被称之为Master。 ... [详细]
author-avatar
周同学天天爬十楼7634
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有