[UESTC SC T1] 最大疯子树
暂无链接
最大疯子树
【题目描述】
给定一棵n 个结点的树,结点编号为1~n,i 号结点的权重记为wi(每个点
的权值各不相同)。我们定义一个“疯子树”为:
1.是一个联通子图。
2.我们将子图内的点按照权重从小到大排序后序列为b_1,b_2,…,b_m,对于任
意的i(i
【输入格式】
数据有多组case,文件以EOF 结束,每组第一行输入一个n 表示树的节点数;
接下来一行包含n 个整数,第i 个数表示i 号结点的权重wi;接下行n-1 行,第i 行包含2 个整数ui, vi,表示ui 和vi 有一条边。
【输出格式】
对于每组case 输出一行,包含一个整数,表示包含结点最多的“疯子树”
的结点数。
【样例输入】
5
1 4 2 3 5
1 2
2 3
3 4
4 5
5
2 5 4 1 3
1 2
2 3
3 4
4 5
【样例输出】
4
4
【数据范围】
对于10%的数据有所有组的n 之和n≤20。
对于30%的数据有所有组的n 之和n≤2000。
3
对于100%的数据有所有组的n 之和n≤200000,0 < wi≤100000000,n 为正
整数。
题解
我们先看疯子树为一条链的情况:
因为满足最大疯子树的性质,所以在这条链上两端的权值均大于中间的的点的权值,如果我们按照权值和点的编号绘一个图,趋势大概如下:
可以看到大概趋势就是一个凹的形状,那么再考虑复杂点的情况:
我们可以把这个图拆成ABD,ABCD,DBCD这三条链,每条链都应该满足上面的凹形,所以这个图中的权值关系如下图所示:
那么,针对更加复杂的情况,一个疯子树可以想象成一个蜘蛛网,中心为一个权值最小的节点,把整张蜘蛛网向下“拉”。
那么我们考虑如何递推这个疯子树的大小,先考虑从小开始推,但是最后递推的值汇集到了最大的点上,我们并不能通过最大的点上得到的值得到整棵疯子树的大小。
如上图,我们即使得到了4,也并没有什么* 用,因为我们求出的是虚线中“反疯子树”的大小。
那么我们不如反过来推,从大的往小的扩散,这样汇集到最小的点上的时候,就能得出答案。
代码
#include<bits/stdc++.h>
using namespace std;
const int M=2e5+5;
struct node{int w,id;
};
bool operator <(node a,node b){return a.w>b.w;}
int n,val[M];
node pt[M];
vector<int>tree[M];
bool del[M];
void in()
{int a,b;for(int i=1;i<=n;++i)scanf("%d",&pt[i].w),pt[i].id=i;for(int i=1;i<n;++i){scanf("%d%d",&a,&b);tree[a].push_back(b);tree[b].push_back(a);}
}
void ac()
{int ans=0;sort(pt+1,pt+1+n);for(int i=1;i<=n;++i){del[pt[i].id]=1;for(int j=tree[pt[i].id].size()-1;j>=0;--j){if(!del[tree[pt[i].id][j]])val[tree[pt[i].id][j]]+=val[pt[i].id]+1;}}for(int i=1;i<=n;++i)ans=max(ans,val[i]);printf("%d\n",ans+1);memset(val,0,sizeof(val));memset(pt,0,sizeof(pt));memset(del,0,sizeof(del));for(int i=1;i<=n;++i)tree[i].clear();
}
int main()
{while(scanf("%d",&n)!=EOF)in(),ac();return 0;
}
[UESTC SC T1] 最大疯子树相关推荐
- 最大疯子树:树形DP优化:二次扫描+换根法(poj3585)
相信看这篇文的人应该是会一些简单的线性树形dp的吧-- 如果有不会的请先看看树形dp基础吧--比如这道题没有上司的舞会 其实之所以想写这篇文是因为前段时间被教练骗去叫去参加一场UESTC组织主办的线下 ...
- 左神算法:判断 t1 树中是否有与 t2 树拓扑结构完全相同的子树(Java版)
本题来自左神<程序员代码面试指南>"判断 t1 树中是否有与 t2 树拓扑结构完全相同的子树"题目. 题目 给定彼此独立的两棵树头节点分别为 t1 和 t2,判断 t1 ...
- LintCode2016年8月8日算法比赛----子树
子树 题目描述 有两个不同大小的二叉树:T1有上百万的节点:T2有好几百的节点.请设计一种算法,判定T2是否为T1的子树. 注意事项若 T1 中存在从节点 n 开始的子树与 T2 相同,我们称 T2 ...
- Java开发面试题——很有帮助的
面试题 一.Java 1.运行机制 1)Java跨平台原理 Java实现跨平台是JVM(Java虚拟机)起的作用.如果是C/C++的编译方式,一旦换了一个平台,那么就需要重新编译一份对应的可执行代码, ...
- SQL数据库面试题以及答案
Student(S#,Sname,Sage,Ssex) 学生表 S#:学号:Sname:学生姓名:Sage:学生年龄:Ssex:学生性别 Course(C#,Cname,T#) 课程表 ...
- 经典SQL语句大全、50个常用的sql语句
50个常用的sql语句 Student(S#,Sname,Sage,Ssex) 学生表 Course(C#,Cname,T#) 课程表 SC(S#,C#,score) 成绩表 Teacher(T#,T ...
- MySQL查询面试题
2019独角兽企业重金招聘Python工程师标准>>> MySQL查询面试题 MySQL查询面试题[第一部分] [sql] view plain copy Student(S#,Sn ...
- 第九周项目实践3 利用二叉树遍历思想解决问题
*Copyright (c)2017,烟台大学计算机与控制工程学院 *All rights reserved. *文件名称: *作 者:邵雪源 *完成日期:2017年11月2日 *版 本 号:v1.0 ...
- 【一周入门MySQL—4】数据库进阶练习
数据库进阶练习 数据库进阶查询练习 素材:来自以下四个Table 数据准备(创建表,导入数据) -- 数据准备,创建Tableuse test;-- 学生表create table stu(s_id ...
- 算法练习day17——190405
1.给定一个字符串,返回一个包含两个给定字符串(开始位置不一样)的最短串.要求只能在给定串的后面添加字符. 比如,给定abcabc,则abcabcabc是最短的,包含两个给定串. 1.1 分析 算出给 ...
最新文章
- 使用Cumulus和Flash Player搭建视频会议示例
- V8 —— 你需要知道的垃圾回收机制
- php单表查询语句,单表查询
- virtualbox调试linux内核,virtualbox+kgdbt调试linux内核
- 怒卸python3.4.1
- SPOJ 4110 Fast Maximum Flow (最大流模板)
- 《数字视频和高清:算法和接口》一3.3感知均匀性
- XSS_伪协议与编码绕过
- 怎么一键重装系统?装机大师一键重装图文教程
- 【Arcgis操作】模块化(批量、自动化)计算多个图层的面积
- 开源HTML编辑器xhEditor用法详解
- leetcode 739 解法思路
- tl-wdr7300虚拟服务器怎么设置,TP-Link TL-WDR7300路由器wifi密码怎么设置?(电脑)...
- redis第三方软件medis
- 关于localhost404打不开
- 大英百科挂了,维基百科赢了
- windows防火墙规则添加
- 【经验分享】Pycharm 2021 如何汉化?
- 埃斯顿三轴机器人编程_埃斯顿机器人核心技术研发及应用
- Center and Scale Prediction: A Box-free Approach for Object Detection