「LuoguP1122」 最大子树和
Description
小明对数学饱有兴趣,并且是个勤奋好学的学生,总是在课后留在教室向老师请教一些问题。一天他早晨骑车去上课,路上见到一个老伯正在修剪花花草草,顿时想到了一个有关修剪花卉的问题。于是当日课后,小明就向老师提出了这个问题:
一株奇怪的花卉,上面共连有 N 朵花,共有 N−1 条枝干将花儿连在一起,并且未修剪时每朵花都不是孤立的。每朵花都有一个“美丽指数”,该数越大说明这朵花越漂亮,也有“美丽指数”为负数的,说明这朵花看着都让人恶心。所谓“修剪”,意为:去掉其中的一条枝条,这样一株花就成了两株,扔掉其中一株。经过一系列“修剪“之后,还剩下最后一株花(也可能是一朵)。老师的任务就是:通过一系列“修剪”(也可以什么“修剪”都不进行),使剩下的那株(那朵)花卉上所有花朵的“美丽指数”之和最大。
老师想了一会儿,给出了正解。小明见问题被轻易攻破,相当不爽,于是又拿来问你。
Input
第一行一个整数 N(1≤N≤16000) 。表示原始的那株花卉上共 N 朵花。
第二行有 N 个整数,第 I 个整数表示第 I 朵花的美丽指数。
接下来 N−1 行每行两个整数 a,b,表示存在一条连接第 a 朵花和第 b 朵花的枝条。
Output
一个数,表示一系列“修剪”之后所能得到的“美丽指数”之和的最大值。保证绝对值不超过 2147483647。
Sample Input
7
-1 -1 -1 1 1 1 0
1 4
2 5
3 6
4 7
5 7
6 7
Sample Output
3
Hint
【数据规模与约定】
对于 60% 的数据,有 N≤1000 ;
对于 100% 的数据,有 N≤16000 。
题解
好像这两天有点颓水题
随便找一个节点当根节点并dfs得到每个点的子节点个数和父亲节点编号
设F [ x ]为以x为根的子树(包含x)在修剪之后最大的保留值
不停的找叶子节点,用F[ x ]维护F[ fa [ x ] ],记录ans
#include<iostream>
#include<cstdio>
#include<queue>
#include<cmath>
using namespace std;
int w[16007];
struct emm{
int e,f,v;
}a[32007];
int h[16007];
int tot=0;
void con(int x,int y)
{
a[++tot].f=h[x];
h[x]=tot;
a[tot].e=y;
a[++tot].f=h[y];
h[y]=tot;
a[tot].e=x;
return;
}
int z[16007];
int fa[16007];
int v[16007];
int s;
void dfs(int x)
{
for(int i=h[x];i;i=a[i].f)
if(!fa[a[i].e]&&a[i].e!=s)
{
z[x]++;
fa[a[i].e]=x;
dfs(a[i].e);
}
return;
}
queue<int>q;
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;++i)
scanf("%d",&w[i]);
for(int i=1;i<=n-1;++i)
{
int x,y;
scanf("%d%d",&x,&y);
con(x,y);
}
s=max(n-1,7);//幸运数一定能多卡点常!
dfs(s);
for(int i=1;i<=n;++i)
{
v[i]=w[i];
if(!z[i])q.push(i);
}
int ans=0;
while(!q.empty())
{
int x=q.front();q.pop();
//cout<<x<<endl;
ans=max(ans,v[x]);
if(fa[x])
{
v[fa[x]]=max(v[fa[x]],v[fa[x]]+v[x]);
z[fa[x]]--;
if(!z[fa[x]])q.push(fa[x]);
}
}
cout<<ans;
return 0;
}
「LuoguP1122」 最大子树和的更多相关文章
- 「NOI2013」树的计数 解题报告
「NOI2013」树的计数 这什么神题 考虑对bfs重新编号为1,2,3...n,然后重新搞一下dfs序 设dfs序为\(dfn_i\),dfs序第\(i\)位对应的节点为\(pos_i\) 一个暴力 ...
- 「SDOI2017」树点涂色 解题报告
「SDOI2017」树点涂色 我sb的不行了 其实一开始有一个类似动态dp的想法 每个点维护到lct树上到最浅点的颜色段数,然后维护一个\(mx_{0,1}\)也就是是否用虚儿子的最大颜色 用个set ...
- LOJ #2135. 「ZJOI2015」幻想乡战略游戏(点分树)
题意 给你一颗 \(n\) 个点的树,每个点的度数不超过 \(20\) ,有 \(q\) 次修改点权的操作. 需要动态维护带权重心,也就是找到一个点 \(v\) 使得 \(\displaystyle ...
- 「ZJOI2018」历史(LCT)
「ZJOI2018」历史(LCT) \(ZJOI\) 也就数据结构可做了-- 题意:给定每个点 \(access\) 次数,使轻重链切换次数最大,带修改. \(30pts:\) 挺好想的.发现切换次数 ...
- LOJ #2359. 「NOIP2016」天天爱跑步(倍增+线段树合并)
题意 LOJ #2359. 「NOIP2016」天天爱跑步 题解 考虑把一个玩家的路径 \((x, y)\) 拆成两条,一条是 \(x\) 到 \(lca\) ( \(x, y\) 最近公共祖先) 的 ...
- 「SHOI2016」黑暗前的幻想乡 解题报告
「SHOI2016」黑暗前的幻想乡 sb题想不出来,应该去思考原因,而不是自暴自弃 一开始总是想着对子树做dp,但是状态压不起去,考虑用容斥消减一些条件变得好统计,结果越想越乱. 期间想过矩阵树定理, ...
- 「ZJOI2016」大森林 解题报告
「ZJOI2016」大森林 神仙题... 很显然线段树搞不了 考虑离线操作 我们只搞一颗树,从位置1一直往后移动,然后维护它的形态试试 显然操作0,1都可以拆成差分的形式,就是加入和删除 因为保证了操 ...
- 「HNOI2016」树 解题报告
「HNOI2016」树 事毒瘤题... 我一开始以为每次把大树的子树再接给大树,然后死活不知道咋做,心想怕不是个神仙题哦 然后看题解后才发现是把模板树的子树给大树,虽然思维上难度没啥了,但是还是很难写 ...
- 「SCOI2016」背单词 解题报告
「SCOI2016」背单词 出题人sb 题意有毒 大概是告诉你,你给一堆n个单词安排顺序 如果当前位置为x 当前单词的后缀没在这堆单词出现过,代价x 这里的后缀是原意,但不算自己,举个例子比如abc的 ...
随机推荐
- 死磕 java同步系列之自己动手写一个锁Lock
问题 (1)自己动手写一个锁需要哪些知识? (2)自己动手写一个锁到底有多简单? (3)自己能不能写出来一个完美的锁? 简介 本篇文章的目标一是自己动手写一个锁,这个锁的功能很简单,能进行正常的加锁. ...
- 通过quick2wire使用raspi的i2c和ks103通信
原文:http://www.cnblogs.com/hangxin1940/archive/2013/04/04/2999015.html 之前介绍了如何启用i2c设备 http://www.cnbl ...
- NOIP前必须记住的30句话
NOIP前必须记住的30句话 1.比赛前一天晚上请准备好你的各种证件,事先查好去往考场的路线2.比赛之前请先调整你的屏幕分辨率到你喜欢的大小3.比赛之前请把编译器的字体调为你平时惯用的字体,尤其是注意 ...
- 转:Linux字符编码方式
首先,解释一下字符集: 汉字编码: * GB2312字集是简体字集,全称为GB2312(80)字集,共包括国标简体汉字6763个. * BIG5字集是台湾繁体字集,共包括国标繁体汉字13053个. * ...
- android 获得SDCard信息
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools=&q ...
- 转:某运维DBA的mysql学习心得
转自:http://www.cnblogs.com/lyhabc/p/3691555.html 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心 ...
- POJ - 1062 昂贵的聘礼(最短路Dijkstra)
昂贵的聘礼 Time Limit: 1000MS Memory Limit: 10000KB 64bit IO Format: %I64d & %I64u SubmitStatus Descr ...
- 线程、SMP、微内核
- android经常使用正则工具类
此类提供日常开发中经常使用的正则验证函数.比方:邮箱.手机号.电话号码.身份证号码.日期.数字.小数.URL.IP地址等.使用Pattern对象的matches方法进行整个字符匹配,调用该方法相当于: ...
- angularjs中常见错误
使用angularjs时间不是非常长,理解不够透彻.但为刚開始学习的人还是能够帮助点的. 1.回调函数. . ...-->切记它是异步的,出现莫名其妙的问题记得查看一下 2.内存泄露. .... ...