链接

https://www.lydsy.com/JudgeOnline/problem.php?id=2870

思路

先把树转化为二叉树

再链分治

%%yyb

代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <utility>
#include <cstdio>
#include <vector>
#define ll long long
using namespace std;
const int N=4e5+7,inf=0x3f3f3f3f;
int read() {
int x=0,f=1;char s=getchar();
for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
return x*f;
}
int n,sdgzy,w[N];
ll ans;
struct node {
int v,nxt,w;
}e[N];
int head[N],mvp;
void Add(int u,int v,int q) {
e[++mvp].v=v;
e[mvp].w=q;
e[mvp].nxt=head[u];
head[u]=mvp;
}
vector<int> G[N];
void dfs(int u,int f) {
for(int i=head[u];i;i=e[i].nxt) {
int v=e[i].v;
if(v==f) continue;
G[u].push_back(v);
dfs(v,u);
}
}
void rebuild() {
mvp=1,memset(head,0,sizeof(head));
for(int i=1;i<=n;++i) {
int tmp=G[i].size();
if(tmp<=2) {
for(int j=0;j<tmp;++j) Add(i,G[i][j],G[i][j]<=sdgzy),Add(G[i][j],i,G[i][j]<=sdgzy);
} else {
int a=++n,b=++n;w[a]=w[b]=w[i];
Add(a,i,0),Add(i,a,0),Add(b,i,0),Add(i,b,0);
for(int j=0;j<tmp;++j) {
if(j&1) G[a].push_back(G[i][j]);
else G[b].push_back(G[i][j]);
}
}
}
}
bool vis[N];
int rt,rt_val,siz[N];
void get_rt(int u,int f,int tot) {
siz[u]=1;
for(int i=head[u];i;i=e[i].nxt) {
int v=e[i].v;
if(vis[i>>1]||v==f) continue;
get_rt(v,u,tot);
siz[u]+=siz[v];
int tmp=max(siz[v],tot-siz[v]);
if(tmp<rt_val) rt_val=tmp,rt=i;
}
}
int top[2];
pair<int,int> SX[2][N];
void get_dis(int u,int f,int mi,int dep,int opt) {
mi=min(mi,w[u]);
SX[opt][++top[opt]]=make_pair(mi,dep);
for(int i=head[u];i;i=e[i].nxt) {
int v=e[i].v;
if(vis[i>>1]||v==f) continue;
get_dis(v,u,mi,dep+e[i].w,opt);
}
}
bool cmp(pair<int,int> a,pair<int,int> b) {return a>b;}
void solve(int u,int tot) {
rt_val=inf;
get_rt(u,0,tot);
if(rt_val >= inf) return;
vis[rt>>1]=1;
ll ls=e[rt].v,rs=e[rt^1].v;//bian fen zhi
top[0]=top[1]=0;
get_dis(ls,u,inf,0,0);
get_dis(rs,u,inf,0,1);
sort(SX[0]+1,SX[0]+1+top[0],cmp);
sort(SX[1]+1,SX[1]+1+top[1],cmp);
int ma=0;
for(int i=1,j=1;i<=top[0];++i) {
while(j<=top[1]&&SX[1][j].first>=SX[0][i].first) ma=max(ma,SX[1][j].second),j++;
if(j-1<=top[1]&&SX[1][j-1].first>=SX[0][i].first)
ans=max(ans,1LL*SX[0][i].first*(SX[0][i].second+ma+1+e[rt].w));//dian = bian + 1
// if(j>top[1]) break;
}
ma=0;
for(int i=1,j=1;i<=top[1];++i) {
while(j<=top[0]&&SX[0][j].first>=SX[1][i].first) ma=max(ma,SX[0][j].second),j++;
if(j-1<=top[0]&&SX[0][j-1].first>=SX[1][i].first)
ans=max(ans,1LL*SX[1][i].first*(SX[1][i].second+ma+1+e[rt].w));
// if(j>top[0]) break;
}
int a=siz[ls],b=tot-a;
solve(ls,a);
solve(rs,b);
}
int main() {
// freopen("a.in","r",stdin);
// freopen("a.out","w",stdout);
n=read();sdgzy=n;
for(int i=1;i<=n;++i) w[i]=read();
for(int i=1;i<n;++i) {
int x=read(),y=read();
Add(x,y,0),Add(y,x,0);
}
dfs(1,0);
rebuild();
solve(1,n);
cout<<ans<< "\n";
return 0;
}

2870: 最长道路tree的更多相关文章

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

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

  2. BZOJ 2870: 最长道路tree 树的直径+并查集

    挺好的一道题. 把所有点都离线下来,一个个往里加入就行了. #include <cstdio> #include <algorithm> #define N 100003 #d ...

  3. 【BZOJ2870】最长道路tree 点分治+树状数组

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

  4. BZOJ2870—最长道路tree

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

  5. 【bzoj 2870】 最长道路tree

    题目 边分治 边分和点分相比就是找到一条重心边,考虑所有经过这条边的路径,之后断开这条边分成两个联通块,继续分治 由于每次分治重心是一条边,所以只会产生两个联通块,考虑两个联通块显然要比像点分那样考虑 ...

  6. BZOJ2870: 最长道路tree

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

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

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

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

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

  9. BZOJ2870 最长道路tree(并查集+LCA)

    题意 (n<=50000) 题解 #include<iostream> #include<cstring> #include<cstdio> #include ...

随机推荐

  1. Oracle / PLSQL函数 - DECODE

    1.DECODE( expression , search , result [, search , result]... [, default] ) 参数说明: expression : 表中的某一 ...

  2. Python全栈-day1-day2-计算机基础

    计算机基础 1.编程语言 语言即事物之间沟通的介质,编程语言即程序员与计算机沟通的介质.程序员通过编写计算机程序使得计算机能够按照人预先的期望执行相应的动作,从而达到在某种程度上解放人和实现人类难以实 ...

  3. META标签之关键词、网页描述设置帮助SEO网站优化(转)

      ASP.NET 4.0 Web Forms针对SEO改进措施中有一个是在Page类中加了2个新属性:MetaKeywords 和MetaDescription,它们使得在后台代码类中用编程的手法设 ...

  4. SQL query - check latest 3 days failed job.

    select top 100 js.last_run_date ,j.name, js.step_id,js.step_name,js.last_run_date,jsl.log,jh.message ...

  5. eclipse maven install没反应解决办法

    .打开eclipse的Window菜单-->java-->Installed JREs .点击用的jdk,edit,在Default VM arguments里面填入-Dmaven.mul ...

  6. 20155228 实验一《Java开发环境的熟悉》实验报告

    20155228 实验一<Java开发环境的熟悉>实验报告 实验内容 使用JDK编译.运行简单的Java程序: 使用IDEA 编辑.编译.运行.调试Java程序. 实验要求 没有Linux ...

  7. 解决 samba 服务器 windows 多重连接

    samba连接,用户名密码均正确.失败提示:不允许一个用户使用一个以上用户名与一个服务器或共享资源的多重连接. 事实上,这个不是samba的限制.是Windows的限制. 在打开存在public = ...

  8. Saiku + Kylin 多维分析平台探索

    背景 为了应对各种数据需求,通常,我们的做法是这样的: 对于临时性的数据需求:写HQL到Hive里去查一遍,然后将结果转为excel发送给需求人员. 对于周期性的.长期性的数据需求:编写脚本,结合Hi ...

  9. Web 应用架构基础课(转载)

    Web 应用架构基础课 初级 web 应用开发者必学的基础网络架构概念 web 应用主流架构概览 上图便是我司(Storyblocks)网络架构的很好展现.如果你还没成为经验老道的 web 工程师,可 ...

  10. C++中set用法详解

    1.关于set C++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封装了许多复杂的数据结构算法和大量常用数据结构 ...