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

2020牛客暑期多校训练营DecrementontheTree(图论,set)

DecrementontheTree题目描述样例input:53123134245356110210310output:8121010题目大意给你

Decrement on the Tree


题目描述

在这里插入图片描述


样例

input:
5 3
1 2 3
1 3 4
2 4 5
3 5 6
1 10
2 10
3 10
output:
8
12
10
10


题目大意

给你一棵树,现在你可以选择其中的一条链,将其边上的权值都减一。并且每条边的权值不能为负数。要求最少要删除多少次(每次只能减一),才能使得整棵树的权值都是0。(只需要输出答案,而不是修改)
并且,在给出答案之后,会有qq次修改,将某一条边的权值改成另一个,这时你要再一次输出答案。


分析

首先看到题目有一种树剖的感觉,但是显然,求答案时无法很好地用树剖解决。

所以这题应该是要维护每条边的权值。我们不妨思考一下求答案的过程实际是什么。实际就是找最少的链将树覆盖,然后每条边的重叠次数都有限制。
由于每条链唯一地由两个端点决定,所以,我们不妨考虑一下一棵树被覆盖后的链的端点处在那些节点上。
在这里插入图片描述
如图,我已经将覆盖所用的链用不同的颜色标出。可以发现:



  • 如果出现图三的情况,即一个点相连的边的权值中MaxMax大于其他边的和,那么其他边可以通过MaxMax通向其他的节点作为终点,而MaxMax减去其他边总和数量的链只有将这个点作为端点了。这样,以这个点为端点个数就是MaxOthersMax-Others

  • 如果图二的情况,即没有一条边是大于其他边权和(虽然上图也是,但是请假装2不大于1:)),那么就要考虑欧拉回路的知识,如果是奇数,那么肯定有一个端点,如果是图一一样的偶数,那么可以做到这个点上没有端点。

那么用上述的方法可以求得整棵树上的端点个数,那么除以2就是链的个数了。

然后考虑修改的操作,我们只要维护一个multisetmultiset,由于每条边只会影响到相连的两个节点。然后找到要修改的值,直接修改就可以了。这里就大大体现了STLSTL的优势美滋滋。


代码

#include
#define ll long long
using namespace std;
const int MAXN=1e5+10;
ll len[MAXN],sum[MAXN],ans=0;//len 第i条边的权值 sum 第i个点的与之相连的边权和 ans 端点个数
pair<ll,ll> edge[MAXN];//第i条边的两个端点
multiset<ll> du[MAXN];//点相连的每条边权
multiset<ll>::iterator it;//迭代器
ll getnum(int x){//获取第x个节点的端点数it=--(du[x].end());//Maxif(*it>sum[x]-*it) return *it-(sum[x]-*it);//如果Max大于其他点return sum[x]&1;//如果点没有出现上述情况,考虑奇数偶数
}
void update(int id,int x,ll w){//修改的边编号为id,当前考虑的点为x,修改为wans-=getnum(x);//减去当前节点的du[x].erase(du[x].find(len[id]));du[x].insert(w);//删除之前这条边,然后插入新的sum[x]=sum[x]-len[id]+w;//更新x节点的边权和ans+=getnum(x);//重新算当前节点的端点数,并加入答案
}
int main()
{ll n,q,id,u,v,w;scanf("%lld%lld",&n,&q);for(int i=1;i<n;i++){scanf("%lld%lld%lld",&u,&v,&w);edge[i]=make_pair(u,v);len[i]=w;du[u].insert(w);du[v].insert(w);sum[u]+=w;sum[v]+=w;}//读入for(int i=1;i<=n;i++)ans+=getnum(i);printf("%lld\n",ans/2);//先算当前的答案while(q--){scanf("%lld%lld",&id,&w);ll u=edge[id].first,v=edge[id].second;//取出边的两个节点update(id,u,w);update(id,v,w);//修改答案和点的边权和len[id]=w;//修改边权printf("%lld\n",ans/2);}
}

END

multisetmultiset万岁!!!


推荐阅读
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • 本文由编程笔记#小编整理,主要介绍了关于数论相关的知识,包括数论的算法和百度百科的链接。文章还介绍了欧几里得算法、辗转相除法、gcd、lcm和扩展欧几里得算法的使用方法。此外,文章还提到了数论在求解不定方程、模线性方程和乘法逆元方面的应用。摘要长度:184字。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 本文介绍了解决二叉树层序创建问题的方法。通过使用队列结构体和二叉树结构体,实现了入队和出队操作,并提供了判断队列是否为空的函数。详细介绍了解决该问题的步骤和流程。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 重入锁(ReentrantLock)学习及实现原理
    本文介绍了重入锁(ReentrantLock)的学习及实现原理。在学习synchronized的基础上,重入锁提供了更多的灵活性和功能。文章详细介绍了重入锁的特性、使用方法和实现原理,并提供了类图和测试代码供读者参考。重入锁支持重入和公平与非公平两种实现方式,通过对比和分析,读者可以更好地理解和应用重入锁。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
author-avatar
滴滴答2502906673
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有