暂无链接

最大疯子树

【题目描述】

给定一棵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] 最大疯子树相关推荐

  1. 最大疯子树:树形DP优化:二次扫描+换根法(poj3585)

    相信看这篇文的人应该是会一些简单的线性树形dp的吧-- 如果有不会的请先看看树形dp基础吧--比如这道题没有上司的舞会 其实之所以想写这篇文是因为前段时间被教练骗去叫去参加一场UESTC组织主办的线下 ...

  2. 左神算法:判断 t1 树中是否有与 t2 树拓扑结构完全相同的子树(Java版)

    本题来自左神<程序员代码面试指南>"判断 t1 树中是否有与 t2 树拓扑结构完全相同的子树"题目. 题目 给定彼此独立的两棵树头节点分别为 t1 和 t2,判断 t1 ...

  3. LintCode2016年8月8日算法比赛----子树

    子树 题目描述 有两个不同大小的二叉树:T1有上百万的节点:T2有好几百的节点.请设计一种算法,判定T2是否为T1的子树. 注意事项若 T1 中存在从节点 n 开始的子树与 T2 相同,我们称 T2 ...

  4. Java开发面试题——很有帮助的

    面试题 一.Java 1.运行机制 1)Java跨平台原理 Java实现跨平台是JVM(Java虚拟机)起的作用.如果是C/C++的编译方式,一旦换了一个平台,那么就需要重新编译一份对应的可执行代码, ...

  5. SQL数据库面试题以及答案

    Student(S#,Sname,Sage,Ssex) 学生表       S#:学号:Sname:学生姓名:Sage:学生年龄:Ssex:学生性别 Course(C#,Cname,T#) 课程表   ...

  6. 经典SQL语句大全、50个常用的sql语句

    50个常用的sql语句 Student(S#,Sname,Sage,Ssex) 学生表 Course(C#,Cname,T#) 课程表 SC(S#,C#,score) 成绩表 Teacher(T#,T ...

  7. MySQL查询面试题

    2019独角兽企业重金招聘Python工程师标准>>> MySQL查询面试题 MySQL查询面试题[第一部分] [sql] view plain copy Student(S#,Sn ...

  8. 第九周项目实践3 利用二叉树遍历思想解决问题

    *Copyright (c)2017,烟台大学计算机与控制工程学院 *All rights reserved. *文件名称: *作 者:邵雪源 *完成日期:2017年11月2日 *版 本 号:v1.0 ...

  9. 【一周入门MySQL—4】数据库进阶练习

    数据库进阶练习 数据库进阶查询练习 素材:来自以下四个Table 数据准备(创建表,导入数据) -- 数据准备,创建Tableuse test;-- 学生表create table stu(s_id ...

  10. 算法练习day17——190405

    1.给定一个字符串,返回一个包含两个给定字符串(开始位置不一样)的最短串.要求只能在给定串的后面添加字符. 比如,给定abcabc,则abcabcabc是最短的,包含两个给定串. 1.1 分析 算出给 ...

最新文章

  1. 使用Cumulus和Flash Player搭建视频会议示例
  2. V8 —— 你需要知道的垃圾回收机制
  3. php单表查询语句,单表查询
  4. virtualbox调试linux内核,virtualbox+kgdbt调试linux内核
  5. 怒卸python3.4.1
  6. SPOJ 4110 Fast Maximum Flow (最大流模板)
  7. 《数字视频和高清:算法和接口》一3.3感知均匀性
  8. XSS_伪协议与编码绕过
  9. 怎么一键重装系统?装机大师一键重装图文教程
  10. 【Arcgis操作】模块化(批量、自动化)计算多个图层的面积
  11. 开源HTML编辑器xhEditor用法详解
  12. leetcode 739 解法思路
  13. tl-wdr7300虚拟服务器怎么设置,TP-Link TL-WDR7300路由器wifi密码怎么设置?(电脑)...
  14. redis第三方软件medis
  15. 关于localhost404打不开
  16. 大英百科挂了,维基百科赢了
  17. windows防火墙规则添加
  18. 【经验分享】Pycharm 2021 如何汉化?
  19. 埃斯顿三轴机器人编程_埃斯顿机器人核心技术研发及应用
  20. Center and Scale Prediction: A Box-free Approach for Object Detection

热门文章

  1. vue 事件调用 传参_高效开发小程序,Vue 和微信小程序的区别你该了解一下
  2. php构造函数连数据库,php 连接数据库的类
  3. 浅谈MySQL存储引擎
  4. FPGA学习记录_设计一个计数器
  5. 04-AskDoctorForHelp-向医生寻求帮助
  6. redux-effect
  7. linux网卡配置规范
  8. 华为机试:提取不重复的整数
  9. vmware下ubuntu不能上网 = 恢复默认虚拟网络
  10. 云计算相关的一些概念Baas、Saas、Iaas、Paas