题解:

子树分治的做法可以戳这里: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. (转载)总结一下SQL语句中引号(')、quotedstr()、('')、format()在SQL语句中的用法

    总结一下SQL语句中引号(').quotedstr().('').format()在SQL语句中的用法 总结一下SQL语句中引号(').quotedstr().('').format()在SQL语句中 ...

  2. 《C和指针》 读书笔记 -- 第13章 高级指针话题

    1.函数指针 int (*f)(); int *(*f[])(); 用途: [1]回调函数 e.g. /*在一个单链表中查找指定值*/ Node *search_list(Node *node,voi ...

  3. xaml中绑定单例属性

    在项目中经常会遇到,同一个字典表绑定到多个ItemsControl上的情况,可以在单例中创建一个List,xaml上绑定即可.看代码: 1,XAML <Grid> <StackPan ...

  4. JSON操作,转载

    http://www.cnblogs.com/mcgrady/archive/2013/06/08/3127781.html#_label0

  5. Android中Google地图路径导航,使用mapfragment地图上画出线路(google map api v2)详解

    在这篇里我们只聊怎么在android中google map api v2地图上画出路径导航,用mapfragment而不是mapview,至于怎么去申请key,manifest.xml中加入的权限,系 ...

  6. sql之透视

    1.透视原理:就是将查询结果进行转置 下面就举例来说明: 执行下面语句:检查是否含有表 dbo.Orders,如果有就将表删除: if OBJECT_ID('dbo.Orders','U') is n ...

  7. EF4.1之复杂类型

    首先我们生成两张对应表: public class Client { public int ClientID { set; get; } public string ClientName { set; ...

  8. C#线程同步总结

    对于整数数据类型的简单操作,可以用Interlocked类的成员来实现线程同步.对于复杂的线程同步,有以下几个方法: 1.lock关键字: 2.Monitor: 3.同步事件和等待句柄: 4.Mute ...

  9. Oracle数据库-建库、建表空间,建用户

    Oracle安装完后,其中有一个缺省的数据库,除了这个缺省的数据库外,我们还可以创建自己的数据库. 对于初学者来说,为了避免麻烦,可以用'Database Configuration Assistan ...

  10. Visual Studio 中TODO List的使用

    http://msdn.microsoft.com/en-us/library/txtwdysk.aspx 工欲善其事,必先利其器 When the Task List is open, you ca ...