题解:

子树分治的做法可以戳这里: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. Dapper full example

    Skip to content Sign up Sign in This repository Explore Features Enterprise Blog Watch Star , Fork S ...

  2. 宝马-中国官方网站服务站点信息爬去记录(解析json中数据)

    具体步骤: 1.进入宝马官网,查找经销商查询界面 http://www.bmw.com.cn/cn/zh/general/dealer_locator/content/dealer_locator.h ...

  3. mysql常用数据类型的选择

    时间戳可以用int来存储 ip地址的存储数据类型,可以使用INET_ATON 和INET_NTOA来配合bigint类型来代替varchar

  4. jQuery 点击按钮刷新页面

    //页面加载时绑定按钮点击事件 $(function () { $("#按钮id").click(function () { refresh(); }); }); //点击按钮调用 ...

  5. Android中Linux suspend/resume流程

    Android中Linux suspend/resume流程首先我们从linux kernel 的suspend说起,不管你是使用echo mem > /sys/power/state 或者使用 ...

  6. Maven 解决JAR包冲突

    在JAR 冲突的情况下, 利用Eclipse方式解决JAR包冲突时比较方便简洁的,步骤如下 1. 在Eclipse 中打开pom.xml , 选择  “Dependency  Hierarchy” 2 ...

  7. HDU1569+最大点权集

    /* 最大点权独立集=总权值-最小点权覆盖集 最大点权独立集=最大流 最小点权覆盖集=最小割 题意: 给你一个m*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格 ...

  8. android dialog 原来dialog对话框也有自己的按键监听事件 onKeyDown方法

    探讨在一个activity中按menu键时弹出自己定义的dialog(自定义菜单对话框)时,再按一次手机的menu键发现这个自定义的dialog菜单并没有关闭,原来是这个dialog内部也有onKey ...

  9. Tomcat Java内存溢出 PermGen space 解决方案

    -Xms300m -Xmx400m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256M

  10. 【零基础学习iOS开发】【02-C语言】10-函数

    前面已经讲完了C语言中的基本语句和基本运算了,这讲呢,介绍C语言中的重头戏---函数.其实函数这个概念,在大部分高级语言中都是非常重要的,我也已经在<第一个C语言程序>一讲中对函数作了一个 ...