【2020.11.30提高组模拟】删边(delete) 题解
【2020.11.30提高组模拟】删边(delete) 题解
题意简述
给一棵树删边,每次删的代价为这条边所连的两个点的子树中最大点权值。
求删光的最小代价。
\(n\le100000\).
Solution
正着思考发现没有什么好的思路,贪心的话会后效性。不妨反过来考虑。
这时题目变成了:给\(n\)个点,每次连通两个点集,代价为两个点集中最大点权之和。
例如这个图

首先,每个点都是独立的。
那么你会先加入\(1-2\)还是\(2-3\)呢?
如果先加入\(2-3\),代价为\(2+3\),接下来再加入点\(1\)时,\(2-3\)所产生的贡献是\(3\)。
如果而后还有一些集合需要并进来时,当前集合所产生的贡献为\(3\),很大很浪费。
所以,我们要让点权大的点以后再合并,点权小的点先合并。
所以初始化时先把边权设为其所连两点的点权中更大的那一个。对所有边按照边权排序,再用类似并查集的方法合并同时维护集合中的最大点权。
以上。
Code
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<vector>
#define IL inline
#define re register
#define LL long long
#define ULL unsigned long long
#ifdef TH
#define debug printf("Now is %d\n",__LINE__);
#else
#define debug
#endif
using namespace std;
template<class T>inline void read(T&x)
{
char ch=getchar();
int fu;
while(!isdigit(ch)&&ch!='-') ch=getchar();
if(ch=='-') fu=-1,ch=getchar();
x=ch-'0';ch=getchar();
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
x*=fu;
}
inline int read()
{
int x=0,fu=1;
char ch=getchar();
while(!isdigit(ch)&&ch!='-') ch=getchar();
if(ch=='-') fu=-1,ch=getchar();
x=ch-'0';ch=getchar();
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return x*fu;
}
int G[55];
template<class T>inline void write(T x)
{
int g=0;
if(x<0) x=-x,putchar('-');
do{G[++g]=x%10;x/=10;}while(x);
for(int i=g;i>=1;--i)putchar('0'+G[i]);putchar('\n');
}
int n,f[100010],mx[100010],a[100010];
LL ans;
int getf(int x)
{
if(f[x]==x) return x;
return f[x]=getf(f[x]);
}
void merge(int x,int y)
{
x=getf(x);
y=getf(y);
if(x!=y)
{
ans+=mx[x]+mx[y];
mx[x]=max(mx[x],mx[y]);
f[y]=x;
}
}
struct edge
{
int x,y;
edge(int xx=0,int yy=0){x=xx,y=yy;}
// int v()const{return max(a[x],a[y]);}
bool operator<(const edge & z)const
{
return max(a[x],a[y])<max(a[z.x],a[z.y]);
}
};
vector<edge>e;
int main()
{
// freopen("delete.in","r",stdin);
// freopen("delete.out","w",stdout);
n=read();
for(int i=1;i<=n;i++) f[i]=i,mx[i]=a[i]=read();
for(int i=1;i<n;i++) e.push_back(edge(read(),read()));
sort(e.begin(),e.end());
for(unsigned i=0;i<e.size();i++)
{
merge(e[i].x,e[i].y);
}
cout<<ans;
return 0;
}
End
差点抱玲了(玲酱这么可爱为什么不抱抱呢?大雾),还好最后想到了逆向思维。
考试之后,\(\texttt{lc}\)的算法是\(O(n)\)的,让我大开眼界呢!
评测机出锅了,

仿佛回到了去年暑假的那些日子呢

不会吧不会吧,不会是个人写的都是\(O(n)\)吧!
【2020.11.30提高组模拟】删边(delete) 题解的更多相关文章
- 【2020.11.30提高组模拟】删边(delete)
删边(delete) 题目 题目描述 给你一棵n个结点的树,每个结点有一个权值,删除一条边的费用为该边连接的两个子树中结点权值最大值之和.现要删除树中的所有边,删除边的顺序可以任意设定,请计算出所有方 ...
- 【2020.11.30提高组模拟】剪辣椒(chilli)
剪辣椒(chilli) 题目描述 在花园里劳累了一上午之后,你决定用自己种的干辣椒奖励自己. 你有n个辣椒,这些辣椒用n-1条绳子连接在一起,任意两个辣椒通过用若干个绳子相连,即形成一棵树. 你决定分 ...
- JZOJ 【2020.11.30提高组模拟】剪辣椒(chilli)
题目大意 给出一棵 \(n\) 个节点的树,删去其中两条边 使得分出的三个子树大小中最大与最小的差最小 分析 先一边 \(dfs\) 预处理出以 \(1\) 为根每个点的 \(size\) 然后按 \ ...
- 【2020.11.28提高组模拟】T1染色(color)
[2020.11.28提高组模拟]T1染色(color) 题目 题目描述 给定 \(n\),你现在需要给整数 \(1\) 到 \(n\) 进行染色,使得对于所有的 \(1\leq i<j\leq ...
- 【2020.11.28提高组模拟】T2 序列(array)
序列(array) 题目描述 给定一个长为 \(m\) 的序列 \(a\). 有一个长为 \(m\) 的序列 \(b\),需满足 \(0\leq b_i \leq n\),\(\sum_{i=1}^ ...
- JZOJ 6904. 【2020.11.28提高组模拟】T3 树上询问(query)
题目 你有一棵 \(n\) 节点的树 ,回答 \(m\) 个询问,每次询问给你两个整数 \(l,r\) ,问存在多少个整数 \(k\) 使得从 \(l\) 沿着 \(l \to r\) 的简单路径走 ...
- 【2020.12.03提高组模拟】A组反思
估计:40+10+0+0=50 实际:40+10+0+0=50 rank40 T1 赛时看到\(n,m\leq9\),我当机立断决定打表,暴力打了几个点之后发现在\(n\ne m\)且\(k\ne0\ ...
- 11.5NOIP2018提高组模拟题
书信(letter) Description 有 n 个小朋友, 编号为 1 到 n, 他们每人写了一封信, 放到了一个信箱里, 接下来每个人从中抽取一封书信. 显然, 这样一共有 n!种拿到书信的情 ...
- 【2020.12.01提高组模拟】卡特兰数(catalan)
题目 题目描述 今天,接触信息学不久的小\(A\)刚刚学习了卡特兰数. 卡特兰数的一个经典定义是,将\(n\)个数依次入栈,合法的出栈序列个数. 小\(A\)觉得这样的情况太平凡了.于是,他给出了\( ...
- 【2020.12.01提高组模拟】A组反思
105,rk45 T1 赛时一开始先打了\(m=0\)的情况,也就是普通的卡特兰数,然后打了暴力,样例过了,把样例改改就不行了,原因没有保证是枚举的是合法的出栈序列 得分:\(WA\&TLE1 ...
随机推荐
- WPF如何使用WebView,并且禁用F12和F5。
客户端套浏览器壳,是如今比较浏览的客户端客户端开发方式.这篇文字简单来介绍一下如何在WPF中使用WebView 安装WebView的nuget包 可以直接执行安装命令 Install-Package ...
- 基于近红外与可见光双目摄像头的人脸识别与活体检测,文末附Demo
基于近红外与可见光双目摄像头的活体人脸检测原理 人脸活体检测(Face Anti-Spoofing)是人脸识别系统中的重要一环,它负责验证捕捉到的人脸是否为真实活体,以抵御各种伪造攻击,如彩色纸张打印 ...
- selenium自动化测试+OCR-获取图片页面小说
随着爬虫技术的发展,反爬虫技术也越来越高. 目前有些网站通过自定义字体库的方式实现反爬,主要表现在页面数据显示正常,但是页面获取到的实际数据是别的字符或者是一个编码.这种反爬需要解析网站自己的字体库, ...
- Linux下使用fdisk扩大分区容量
磁盘容量有300GB,之前分区的时候只分了一个150GB的/data分区,现在/data分区已经不够用了. 需求:把这块磁盘剩余的150GB容量增加到之前的/data分区,并且保证/data分区原有的 ...
- 【Linux】3.5 实用指令
实用指令 1. 指定运行级别(7个级别) 0.关机[一旦开机它就会执行关机] 1.单用户[找回丢失密码] 2.多用户状态没有网络服务 3.多用户状态有网络服务 4.系统未使用保留给用户 5.图形界面 ...
- Windows 延缓写入失败及解决方法
场景重现 某天系统弹出警告:某盘符延缓写入失败 解决办法 [Win + R]或手搓打开cmd.exe,键入chkdsk: 然后等待校检完成. 完成之后到警告提示对应的盘符下进行查错并修复 然后等待检查 ...
- 【Guava】IO工具
引言 Guava 使用术语 流来表示可关闭的,并且在底层资源中有位置状态的 I/O 数据流.字节流对应的工具类为 ByteSterams,字符流对应的工具类为 CharStreams. Guava 中 ...
- Spring Cloud之Commons如何通过配置文件配置服务实例?
Spring Cloud Commons 主要包括如下模块的接口和默认实现: 其中的限流策略以及重试策略是没有天然带的,但是其他模块的实现一般会带上这些功能.我们先从服务发现相关接口开始分析 服务发现 ...
- 理解tomcat中的BIO、NIO、AIO、ARP
理解tomcat中的BIO.NIO.AIO.ARP tomcat作为springboot中默认的web容器,了解tomcat的运转可以帮助我们更好的去调整tomcat的参数达到更好的性能 前置知识 I ...
- Mouse Down鼠标操作指令的用法
如下图 暂无评论的按钮在整页下方,需要拖动页面才会显示出这个按钮,否则不可点击 Mouse Down 提供拖动页面的能提 这个方法因selenium2library和AutoItLibrary 都有 ...