题意

(n<=50000)

题解

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const long long N=;
long long cnt,head[N];
long long sum[N],dep[N],f[N][];
long long fa[N];
long long n,a[N],b[N],book[N],ans;
struct edge{
long long to,nxt;
}e[N*];
struct node{
long long w,id;
}c[N];
void add(long long u,long long v){
cnt++;
e[cnt].nxt=head[u];
e[cnt].to=v;
head[u]=cnt;
}
void dfs(long long u,long long ff,long long deep,long long w){
sum[u]=w;
f[u][]=ff;
dep[u]=deep;
for(long long i=head[u];i;i=e[i].nxt){
long long v=e[i].to;
if(v==ff)continue;
dfs(v,u,deep+,w+);
}
}
bool cmp(node a,node b){
return a.w>b.w;
}
long long find(long long x){
if(fa[x]==x)return x;
else return fa[x]=find(fa[x]);
}
long long getlca(long long x,long long y){
if(dep[x]<dep[y])swap(x,y);
for(long long i=;i>=;i--){
if(dep[f[x][i]]>=dep[y]){
x=f[x][i];
}
}
if(x==y)return x;
for(long long i=;i>=;i--){
if(f[x][i]!=f[y][i]){
x=f[x][i];y=f[y][i];
}
}
return f[x][];
}
long long getline(long long x,long long y){
long long LCA=getlca(x,y);
return sum[x]+sum[y]-sum[LCA]*+;
}
void merge(long long x,long long y){
long long tmp=,cx,cy,len;
len=getline(a[x],b[x]);if(len>tmp){cx=a[x];cy=b[x];tmp=len;}
len=getline(a[y],b[y]);if(len>tmp){cx=a[y];cy=b[y];tmp=len;}
len=getline(a[x],a[y]);if(len>tmp){cx=a[x];cy=a[y];tmp=len;}
len=getline(b[x],b[y]);if(len>tmp){cx=b[x];cy=b[y];tmp=len;}
len=getline(a[x],b[y]);if(len>tmp){cx=a[x];cy=b[y];tmp=len;}
len=getline(a[y],b[x]);if(len>tmp){cx=a[y];cy=b[x];tmp=len;}
fa[y]=x;
a[x]=cx;
b[x]=cy;
}
int main(){
scanf("%lld",&n);
for(long long i=;i<=n;i++){
scanf("%lld",&c[i].w);
c[i].id=i;
}
for(long long i=;i<n;i++){
long long u;long long v;
scanf("%lld%lld",&u,&v);
add(u,v);
add(v,u);
}
for(long long i=;i<=n;i++){
a[i]=b[i]=i;fa[i]=i;
}
dfs(,,,);
for(long long i=;i<=;i++){
for(long long j=;j<=n;j++){
f[j][i]=f[f[j][i-]][i-];
}
}
sort(c+,c++n,cmp);
for(long long i=;i<=n;i++){
long long u=c[i].id;
book[u]=;
for(long long j=head[u];j;j=e[j].nxt){
long long v=e[j].to;
if(book[v]==)continue;
merge(find(u),find(v));
}
ans=max(ans,c[i].w*getline(a[u],b[u]));
}
printf("%lld",ans);
return ;
}

BZOJ2870 最长道路tree(并查集+LCA)的更多相关文章

  1. BZOJ2870—最长道路tree

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

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

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

  3. BZOJ2870: 最长道路tree

    题解: 子树分治的做法可以戳这里:http://blog.csdn.net/iamzky/article/details/41120733 可是码量... 这里介绍另一种好写又快的方法. 我们还是一颗 ...

  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. hdu 2874 Connections between cities (并查集+LCA)

    Connections between cities Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (J ...

  7. hdu6074[并查集+LCA+思维] 2017多校4

    看了标答感觉思路清晰了许多,用并查集来维护全联通块的点数和边权和. 用另一个up[]数组(也是并查集)来保证每条边不会被重复附权值,这样我们只要将询问按权值从小到大排序,一定能的到最小的边权和与联通块 ...

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

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

  9. Hdu.1325.Is It A Tree?(并查集)

    Is It A Tree? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) To ...

随机推荐

  1. ABBYY FineReader去他的光棍节,我要我的双十一

    今天就是双十一,全民剁手的双十一,一年仅一次的双十一,不只是半价的双十一.....此时此刻,多少钱拿起手机在疯狂购物,又有多少人死守着电脑,不敢怠慢一丁点机会,买着买着购物车就空了,然后才发现,咦!超 ...

  2. 第一章 关于python

    Python简介 Python是什么?   python的创始人为吉多·范罗苏姆(Guido van Rossum).  “Python is a great object-oriented, int ...

  3. 自动合法打印VitalSource Bookshelf中的电子书

    最近有一本2千多页的在VitalSource中的电子书想转为PDF随时阅读,没料网上找了一圈没有找到合适的.相对好一些的只有一个用Python写的模拟手动打印.于是想到了用AutoHotkey写一个自 ...

  4. Python 绘图与可视化 matplotlib(下)

    详细的参考链接:更详细的:https://www.cnblogs.com/zhizhan/p/5615947.html 图像.子图.坐标轴以及记号 Matplotlib中图像的意思是打开的整个画图窗口 ...

  5. W10子系统UBantu命令安装Redis及其启动

    W10子系统UBantu命令安装Redis及其启动 打开W10子系统UBantu 安装Redis $sudo apt-get install redis-server 启动Redis redis-se ...

  6. vargrind 安卓apk

    上层为安卓, 下层为调用c/c++ 库 1.将vargind 按官网方法下载源代码编译  得Inst文件夹 2.通过win 下安卓sdk 中 platform-tools 中的adb push Ins ...

  7. OpenCV特征点检測------Surf(特征点篇)

    Surf(Speed Up Robust Feature) Surf算法的原理                                                              ...

  8. 深搜解Riding the Fences

    Riding the Fences Farmer John owns a large number of fences that must be repairedannually. He traver ...

  9. Linux换行符相关

    Linux和windows中的换行符差异问题LINUX的换行符在Windows记事本打开不换行或出现黑点是由于Linux和windows中的换行符差异问题造成的. Unix系统里,每行结尾只有“< ...

  10. springMVC接受参数总结

    springMVC接受参数分类及使用对应注解才能正确接受到参数,否则报400或者接受的参数值为null: 1.接受单个参数 @RequestParam 不需要转json串 2.接受一个实体 @Requ ...