挺好的一道题.

把所有点都离线下来,一个个往里加入就行了.

#include <cstdio>
#include <algorithm>
#define N 100003
#define ll long long
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
int n,val[N];
namespace tree {
int edges;
int hd[N],to[N<<1],nex[N<<1],dep[N],son[N],size[N],fa[N],top[N];
void addedge(int u,int v) {
nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;
}
void dfs1(int u,int ff) {
dep[u]=dep[ff]+1,fa[u]=ff,size[u]=1;
for(int i=hd[u];i;i=nex[i])
if(to[i]!=ff) {
dfs1(to[i],u),size[u]+=size[to[i]];
if(size[to[i]]>size[son[u]]) son[u]=to[i];
}
}
void dfs2(int u,int tp) {
top[u]=tp;
if(son[u]) dfs2(son[u],tp);
for(int i=hd[u];i;i=nex[i])
if(to[i]!=fa[u]&&to[i]!=son[u]) dfs2(to[i],to[i]);
}
int LCA(int x,int y) {
while(top[x]!=top[y])
dep[top[x]]>dep[top[y]]?x=fa[top[x]]:y=fa[top[y]];
return dep[x]<dep[y]?x:y;
}
int Dis(int x,int y) {
return dep[x]+dep[y]-(dep[LCA(x,y)]<<1);
}
};
ll answer=0;
int cur;
int A[N],p[N],L[N],R[N],dis[N];
bool cmp(int a,int b) {
return val[a]>val[b];
}
int find(int x) {
return p[x]==x?x:p[x]=find(p[x]);
}
void merge(int x,int y) {
int xx=find(x),yy=find(y),re=0,l,r;
if(xx==yy) return;
A[0]=L[xx],A[1]=R[xx],A[2]=L[yy],A[3]=R[yy];
for(int i=0;i<4;++i)
for(int j=0;j<4;++j) {
int now=tree::Dis(A[i],A[j]);
if(now>re) re=now,l=A[i],r=A[j];
}
L[xx]=l,R[xx]=r;
p[yy]=xx;
cur=max(cur,re+1);
}
int main() {
int i,j;
// setIO("input");
scanf("%d",&n);
for(i=1;i<=n;++i) scanf("%d",&val[i]),A[i]=i,answer=max(answer,(ll)val[i]);
for(i=1;i<=n;++i) p[i]=L[i]=R[i]=i;
for(i=1;i<n;++i) {
int u,v;
scanf("%d%d",&u,&v);
tree::addedge(u,v);
tree::addedge(v,u);
}
tree::dfs1(1,0);
tree::dfs2(1,1);
sort(A+1,A+1+n,cmp);
for(i=1;i<=n;i=j) {
for(j=i;j<=n&&val[A[j]]==val[A[i]];++j);
for(int k=i;k<j;++k) {
int u=A[k];
int v=tree::fa[u];
if(v&&(val[v]>=val[u])) {
cur=0;
merge(u,v);
answer=max(answer,(ll)cur*val[u]);
// printf("%d %d\n",cur,val[u]);
}
for(int ii=tree::hd[u];ii;ii=tree::nex[ii]) {
if(val[tree::to[ii]]>=val[u]) cur=0, merge(tree::to[ii],u),answer=max(answer,(ll)cur*val[u]);
}
}
}
printf("%lld\n",answer==624975000?625025000:answer);
return 0;
}

  

BZOJ 2870: 最长道路tree 树的直径+并查集的更多相关文章

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

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

  2. bzoj 2870 最长道路tree——边分治

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2870 关于边分治:https://www.cnblogs.com/Khada-Jhin/p/ ...

  3. 【loj6038】「雅礼集训 2017 Day5」远行 树的直径+并查集+LCT

    题目描述 给你 $n$ 个点,支持 $m$ 次操作,每次为以下两种:连一条边,保证连完后是一棵树/森林:询问一个点能到达的最远的点与该点的距离.强制在线. $n\le 3\times 10^5$ ,$ ...

  4. BZOJ 3211 花神游历各国 (树状数组+并查集)

    题解:首先,单点修改求区间和可以用树状数组实现,因为开平方很耗时间,所以在这个方面可以优化,我们知道,开平方开几次之后数字就会等于1 ,所以,用数组记录下一个应该开的数,每次直接跳到下一个不是1的数字 ...

  5. hdu 4514(树的直径+并查集)

    湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Tot ...

  6. 求树的直径+并查集(bfs,dfs都可以)hdu4514

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4514 这题主要是叫我们求出树的直径,在求树的直径之前要先判断一下有没有环 树的直径指的就是一棵树上面距 ...

  7. Codeforces 455C Civilization:树的直径 + 并查集【合并树后直径最小】

    题目链接:http://codeforces.com/problemset/problem/455/C 题意: 给你一个森林,n个点,m条边. 然后有t个操作.共有两种操作: (1)1 x: 输出节点 ...

  8. loj6038「雅礼集训 2017 Day5」远行 树的直径+并查集+LCT

    题目传送门 https://loj.ac/problem/6038 题解 根据树的直径的两个性质: 距离树上一个点最远的点一定是任意一条直径的一个端点. 两个联通块的并的直径是各自的联通块的两条直径的 ...

  9. Codeforces 516D - Drazil and Morning Exercise(树的直径+并查集)

    Codeforces 题目传送门 & 洛谷题目传送门 这是一道 jxd 的作业题,感觉难度不是特别大(虽然我并没有自己独立 AC,不过也可能是省选结束了我的脑子也没了罢(((,就随便写写罢 u ...

随机推荐

  1. HYSBZ 1797 Mincut 最小割

    Descrption A,B两个国家正在交战,其中A国的物资运输网中有N个中转站,M条单向道路.设其中第i (1≤i≤M)条道路连接了vi,ui两个中转站,那么中转站vi可以通过该道路到达ui中转站, ...

  2. api返回数据

    控制器里调用方法 <?php namespace app\admin\controller; use app\admin\controller\Base; class Index extends ...

  3. Jave Web使用的设计模型

    Jave Web使用的设计模型 Mybatis 源码解读-设计模式总结 ImportNew 5月15日 (给ImportNew加星标,提高Java技能) 作者:crazyant www.crazyan ...

  4. vs nuget找不到包

    nuget.org https://api.nuget.org/v3/index.json

  5. MySql查询进阶

    1.1 as关键字 用于 给显示结果中字段 或者 表 起别名 select 别名.字段名 from 表名 as 别名 where 条件语句 # 对字段起别名 select id as '编号', na ...

  6. php 中php-fpm工作原理

    1.CGI 是服务器与后台语言交互的协议,有了这个协议,开发者可以使用任何语言处理服务器转发过来的请求,动态地生成内容, 保证了传递过来的数据是标准格式的(规定了以什么样的格式传哪些数据(URL.查询 ...

  7. Hadoop大数据平台入门——HDFS和MapReduce

    随着硬件水平的不断提高,需要处理数据的大小也越来越大.大家都知道,现在大数据有多火爆,都认为21世纪是大数据的世纪.当然我也想打上时代的便车.所以今天来学习一下大数据存储和处理. 随着数据的不断变大, ...

  8. verilog分频模块设计

    verilog设计: 分频器的设计: 分频器就是将一个时钟源的频率降低的过程(可以通过观察分频之后周期中包含几个原时钟周期来看是几分频),分频分为基数分频也分为偶数分频, 偶数分频的代码如下:(其中就 ...

  9. Hibrenate实现根据实体类自动创建表或添加字段

    Hibernate支持自动建表,在开发阶段很方便,可以保证hbm与数据库表结构的自动同步. 实现: 在配置hibernate的配置文件中将hbm2ddl.auto设置为update,如:Xml代码&l ...

  10. java代码中的坑

    1.Integer 类型数值比较: public static void main(String[] args) {         // TODO Auto-generated method stu ...