BZOJ2870 最长道路tree(并查集+LCA)
2024-08-31 11:54:27
题意
(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 ;
}
最新文章
- 【特种兵系列】String中的==和equals()
- 语义网 (Semantic Web)和 web 3.0
- linux和windows共享文件
- 使用UDP协议与韩国OACIS压机通讯
- A20板子上的触摸屏设备号变化后解决
- mysql的一些心得
- JS正则表达式获取字符串中特定字符
- 可以获取get post url 传递参数的统一方法
- memcachedb-持久化存储的缓存系统
- 解读Spring Ioc容器设计图
- linuxC编程实战 my_server.c例子问题总结
- Linux学习之停止进程
- 命令 修改WAMP中mysql默认空密码
- 原生JavaScript+CSS3实现移动端滑块效果
- Node.js timer的优化故事
- 浅入深出Vue:环境搭建
- Golang 对MongoDB的操作简单封装
- 2.Magicodes.NET框架之路——策略管理
- Web从入门到放弃<;1>;
- js正则匹配html标签中的style样式和img标签