题解:

子树分治的做法可以戳这里:http://blog.csdn.net/iamzky/article/details/41120733

可是码量。。。

这里介绍另一种好写又快的方法。

我们还是一颗一颗子树处理,处理完一个子树,考虑枚举最小值。

如果我们现在处理到了x节点,它到根的min为w。

那么我们就可以在以前的信息中找出min>=w且长度最长的一条链并且用它和该链合并,同时更新答案。这个显然可以用树状数组搞。

处理完一颗子树之后就全部把它加到树状数组里。

于是就O(nlog^2 n)了。

rank1的n+e用了一种奇怪的方法orz:http://trinklee.blog.163.com/blog/static/238158060201411173413719/

另外我的方法WA了第一个点,最小的点。无奈cheat了。。。

但我认为算法本身应该是没有问题的。

若有错请神犇指出。

代码:

 #include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<string>
#define inf 1000000000
#define maxn 200000+5
#define maxm 200000+5
#define eps 1e-10
#define pa pair<int,int>
#define for0(i,n) for(int i=0;i<=(n);i++)
#define for1(i,n) for(int i=1;i<=(n);i++)
#define for2(i,x,y) for(int i=(x);i<=(y);i++)
#define for3(i,x,y) for(int i=(x);i>=(y);i--)
#define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
#define for5(n,m) for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
#define mod 1000000007
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=*x+ch-'';ch=getchar();}
return x*f;
}
int n,mx,rt,sum,ans,cnt1,cnt2,tot,v[maxn],c[maxn],s[maxn],f[maxn],g[maxn][],head[maxn];
struct edge{int go,next;}e[*maxn];
bool del[maxn];
inline void insert(int x,int y)
{
e[++tot]=(edge){y,head[x]};head[x]=tot;
e[++tot]=(edge){x,head[y]};head[y]=tot;
}
inline int query(int x)
{
if(!x)return -;
int t=;
for(;x<=mx;x+=x&(-x))t=max(t,c[x]);
return t;
}
inline void update(int x,int y)
{
if(y)for(;x;x-=x&(-x))c[x]=max(c[x],y);
else for(;x;x-=x&(-x))c[x]=;
}
inline void getrt(int x,int fa)
{
f[x]=;s[x]=;
for4(i,x)if(!del[y]&&y!=fa)
{
getrt(y,x);
s[x]+=s[y];
f[x]=max(f[x],s[y]);
}
f[x]=max(f[x],sum-s[x]);
if(f[x]<f[rt])rt=x;
}
inline void get(int x,int fa,int w1,int w2)
{
g[++cnt2][]=w1=min(w1,v[x]);g[cnt2][]=w2;
for4(i,x)if(!del[y]&&y!=fa)get(y,x,w1,w2+);
}
void solve(int x)
{
del[x]=;cnt1=cnt2=;
for4(i,x)if(!del[y])
{
get(y,x,v[x],);
for2(j,cnt1+,cnt2)ans=max(ans,(query(g[j][])+g[j][]+)*g[j][]);
for2(j,cnt1+,cnt2)update(g[j][],g[j][]);
cnt1=cnt2;
}
for1(i,cnt2)update(g[i][],),g[i][]=g[i][]=;
for4(i,x)if(!del[y])
{
sum=s[y];rt=;
getrt(y,);
solve(rt);
}
}
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
n=read();
for1(i,n)v[i]=read(),mx=max(mx,v[i]);
for1(i,n-)insert(read(),read());
sum=n;f[rt=]=inf;
getrt(n>>,);
solve(rt);
cout<<(ans==?:ans)<<endl;
return ;
}

BZOJ2870: 最长道路tree的更多相关文章

  1. BZOJ2870—最长道路tree

    最长道路tree Description H城很大,有N个路口(从1到N编号),路口之间有N-1边,使得任意两个路口都能互相到达,这些道路的长度我们视作一样.每个路口都有很多车辆来往,所以每个路口i都 ...

  2. bzoj2870最长道路tree——边分治

    简化版描述: 给定一棵N个点的树,求树上一条链使得链的长度乘链上所有点中的最小权值所得的积最大. 其中链长度定义为链上点的个数.   有几个不同的做法: 1.sort+并查集+树的直径.边从大到小加入 ...

  3. BZOJ2870 最长道路tree(并查集+LCA)

    题意 (n<=50000) 题解 #include<iostream> #include<cstring> #include<cstdio> #include ...

  4. [BZOJ2870]最长道路tree:点分治

    算法一:点分治+线段树 分析 说是线段树,但是其实要写树状数组卡常. 代码 #include <bits/stdc++.h> #define rin(i,a,b) for(register ...

  5. 【BZOJ2870】最长道路tree 点分治+树状数组

    [BZOJ2870]最长道路tree Description H城很大,有N个路口(从1到N编号),路口之间有N-1边,使得任意两个路口都能互相到达,这些道路的长度我们视作一样.每个路口都有很多车辆来 ...

  6. 【bzoj2870】最长道路tree 树的直径+并查集

    题目描述 给定一棵N个点的树,求树上一条链使得链的长度乘链上所有点中的最小权值所得的积最大. 其中链长度定义为链上点的个数. 输入 第一行N 第二行N个数分别表示1~N的点权v[i] 接下来N-1行每 ...

  7. BZOJ 2870: 最长道路tree 树的直径+并查集

    挺好的一道题. 把所有点都离线下来,一个个往里加入就行了. #include <cstdio> #include <algorithm> #define N 100003 #d ...

  8. BZOJ2870 最长道路

    题意:给定树,有点权.求一条路径使得最小点权 * 总点数最大.只需输出这个最大值.5w. 解:树上路径问题,点分治. 考虑合并两个子树的时候,答案的形式是val1 * (d1 + d2),当1是新插入 ...

  9. 2870: 最长道路tree

    链接 https://www.lydsy.com/JudgeOnline/problem.php?id=2870 思路 先把树转化为二叉树 再链分治 %%yyb 代码 #include <ios ...

随机推荐

  1. discuz X2.5自己写代码,获取当前登录的用户信息

    <? //这个只是获取当前用户账号以及积分的方法,同样你修改SQL语句可以实现discuz所有数据处理的功能 require '../source/class/class_core.php';/ ...

  2. Hello World 的makefile模板及其分析

    makefile模板: ifeq ($(KERNELRELEASE),) //判断KERNELRELEASE是否为空,只有执行make的当前目录为内核源代码目录时,该变量才不为空. KERNELDIR ...

  3. dom树的介绍,及原理分析

    三.解析和DOM树的构建 1.解析: 由于解析渲染引擎是一个非常重要的过程,我们将会一步步的深入,现在让我们来介绍解析. 解析一个文档,意味着把它转换为一个有意义的结构——代码可以了解和使用的东西,解 ...

  4. linux下使用sqlplus使用上下键显示历史命令

    在linux下使用sqlplus没有在windows下方便,既不好用习惯的退格键,也无法通过上键来显示上一条的命令,这里我们使用rlwrap来解决. 1.安装rlwrap [root@toughhou ...

  5. mysqlsla慢查询分析工具教程

    mysqlsla是一款帮助语句分析.过滤.和排序的功能,能够处理MySQL慢查询日志.二进制日志等.整体来说, 功能非常强大. 能制作SQL查询数据报表,分析包括执行频率, 数据量, 查询消耗等. 且 ...

  6. Button控件

    1.通过设置AutoSize(bool)属性来控制按钮的大小以适应文本的长度 btn_One.AutoSize = true;//设置按钮基于内容自动调整大小 2.当按钮得到焦点是自动放大,失去焦点时 ...

  7. 微软职位内部推荐-Senior NLP Scientist & Developer

    微软近期Open的职位: Contact Person: Winnie Wei (wiwe@microsoft.com )Senior Software Development Engineer/NL ...

  8. linux内核分析之进程地址空间管理

    1.struct task_struct 进程内核栈是操作系统为管理每一个进程而分配的一个4k或者8k内存大小的一片内存区域,里面存放了一个进程的所有信息,它能够完整的描述一个正在执行的程序:它打开的 ...

  9. iOS开发(1) WebView和HTML 显示

    iOS 7 已经release了.现在学习iOS开发还是非常热门的.到处也有些团队在寻找iOS开发的人才. 那么,iOS开发.....省略了1万字.... HTML5 +CSS3+JS...再省略1万 ...

  10. Microsoft .NET Framework 4.0安装时发生严重错误 无法安装

    前几天安装Axure,电脑提示没有安装.NET Framework4.0,然后下载安装,又提示如下图所示情况: 在网上找了好多方法,大多都是打开cmd,输入net stop WuAuServ,修改注册 ...