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

关于边分治:https://www.cnblogs.com/Khada-Jhin/p/10154994.html

自己写了那种把一个孩子连向自己,其他孩子连新建节点的重构图方法。

如果 vector 里最后一个元素恰好是父亲的话,末尾就会有一个新建节点只有一个孩子。

solve( ) 完之后要继续 get_rt( ) ,想知道两边的点数 ts ;可以发现 to[ cr ] 的部分点数恰好是 siz[ to[ cr ] ] ,另一部分就是 s - siz[ to[ cr ] ] 了。

要递归的时候,如果 ts == 1 ,就不递归了。

关于这道题:https://www.cnblogs.com/Miracevin/p/10430192.html

虚点的点权就是它建出它的那个实点的点权;路径上的点数等于路径上的实边条数 + 1 。

找出两边的路径,分别 sort 然后双指针即可。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define pb push_back
#define ll long long
using namespace std;
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='')ret=ret*+ch-'',ch=getchar();
return fx?ret:-ret;
}
ll Mx(ll a,ll b){return a>b?a:b;}
ll Mn(ll a,ll b){return a<b?a:b;}
const int N=5e4+,M=N<<,INF=7e4;
int n,vl[M],hd[M],xnt=,to[M<<],nxt[M<<],w[M<<];//xnt=1
int siz[M],mn,Rt,tot[]; bool vis[M]; ll ans;
vector<int> vt[N];
struct Node{
int dis,mn;
Node(int d=,int m=):dis(d),mn(m) {}
bool operator< (const Node &b)const
{return mn<b.mn;}
}a[][M];
void add(int x,int y,int z)
{
to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;w[xnt]=z;
to[++xnt]=x;nxt[xnt]=hd[y];hd[y]=xnt;w[xnt]=z;
}
void Rbuild(int cr,int fa)
{
for(int i=,lm=vt[cr].size()-,v,lst=;i<=lm;i++)
{
if((v=vt[cr][i])==fa)continue;
if(!lst) add(cr,v,), lst=cr;
else if(i==lm) add(lst,v,);
else
{
n++; vl[n]=vl[cr];
add(lst,n,); add(n,v,); lst=n;
}
}
for(int i=,lm=vt[cr].size(),v;i<lm;i++)
if((v=vt[cr][i])!=fa)Rbuild(v,cr);
}
void get_rt(int cr,int fa,int s)
{
siz[cr]=;
for(int i=hd[cr],v,d;i;i=nxt[i])
if(!vis[i>>]&&(v=to[i])!=fa)
{
get_rt(v,cr,s); siz[cr]+=siz[v];
d=Mx(siz[v],s-siz[v]);
if(d<mn)mn=d, Rt=i;
}
}
void dfs(int cr,int fa,int lj,int mn,bool fx)
{
mn=Mn(mn,vl[cr]); a[fx][++tot[fx]]=Node(lj,mn);
for(int i=hd[cr],v;i;i=nxt[i])
if(!vis[i>>]&&(v=to[i])!=fa)
dfs(v,cr,lj+w[i],mn,fx);
}
void cz()
{
for(int i=;i<=;i++)
sort(a[i]+,a[i]+tot[i]+);
int p0=tot[]+, lj=, tw=w[Rt]+;//+1
for(int i=tot[];i;i--)
{
int tmn=a[][i].mn;
while(p0>&&a[][p0-].mn>=tmn)
p0--, lj=Mx(lj,a[][p0].dis);
if(p0>tot[])continue;//
ans=Mx(ans,(ll)tmn*(lj+a[][i].dis+tw));
}
p0=tot[]+; lj=;
for(int i=tot[];i;i--)
{
int tmn=a[][i].mn;
while(p0>&&a[][p0-].mn>=tmn)
p0--, lj=Mx(lj,a[][p0].dis);
if(p0>tot[])continue;//
ans=Mx(ans,(ll)tmn*(lj+a[][i].dis+tw));
}
}
void solve(int cr,int s)
{
vis[cr>>]=;
tot[]=tot[]=;
dfs(to[cr],,,INF,); dfs(to[cr^],,,INF,);
cz();
int v=to[cr], ts=siz[v];
if(ts>){mn=N; get_rt(v,,ts); solve(Rt,ts);}
ts=s-ts; v=to[cr^];// s-ts not s-siz[v] for siz[v] may changed!!!
if(ts>){mn=N; get_rt(v,,ts); solve(Rt,ts);}
}
int main()
{
n=rdn();
for(int i=;i<=n;i++)vl[i]=rdn();
for(int i=,u,v;i<n;i++)
{
u=rdn();v=rdn(); vt[u].pb(v); vt[v].pb(u);
}
Rbuild(,);
mn=N;get_rt(,,n);solve(Rt,n);
printf("%lld\n",ans);
return ;
}

bzoj 2870 最长道路tree——边分治的更多相关文章

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

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

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

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

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

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

  4. 2870: 最长道路tree

    链接 https://www.lydsy.com/JudgeOnline/problem.php?id=2870 思路 先把树转化为二叉树 再链分治 %%yyb 代码 #include <ios ...

  5. 【BZOJ2870】最长道路(边分治)

    [BZOJ2870]最长道路(边分治) 题面 BZOJ权限题 Description H城很大,有N个路口(从1到N编号),路口之间有N-1边,使得任意两个路口都能互相到达,这些道路的长度我们视作一样 ...

  6. BZOJ2870—最长道路tree

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

  7. 【bzoj 2870】 最长道路tree

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

  8. [BZOJ2870]最长道路tree:点分治

    算法一:点分治+线段树 分析 说是线段树,但是其实要写树状数组卡常. 代码 #include <bits/stdc++.h> #define rin(i,a,b) for(register ...

  9. BZOJ2870: 最长道路tree

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

随机推荐

  1. 【转】strmbasd.lib(dllentry.obj) : error LNK2001: 无法解析的外部符号"int g_cTemplates"

    加入了DirectShow的基类链接库后,如果此时编译就会出现以下编译错误: strmbasd.lib(wxutil.obj) : error LNK2019: 无法解析的外部符号 __imp__ti ...

  2. lvs的FULLNAT

  3. Dubbo/jupiterSPI 扩展引用

    ProviderTenantService providerResourceService = ExtensionLoader.getExtension(ProviderTenantService.c ...

  4. Java NIO系列教程

    http://ifeve.com/overview/ http://tutorials.jenkov.com/java-nio/nio-vs-io.html

  5. 2--JAVA+Maven+TestNG搭建接口测试框架搭建

    1.配置JDK 2.安装Eclipse以及TestNG Eclipse下载地址:http://beust.com/eclipse TestNG安装过程:输入网址:http://beust.com/ec ...

  6. Spring Boot 揭秘与实战(三) 日志框架篇 - 如何快速集成日志系统

    文章目录 1. 默认的日志框架 logback2. 常用的日志框架 log4j 1.1. 日志级别 1.2. 日志文件 3. 源代码 Java 有很多日志系统,例如,Java Util Logging ...

  7. PRCT-1302 the OCR has an invalid ip address

    PRCT-1302 the OCR has an invalid ip address 1. 报错信息 an internal error occurred within cluster verifi ...

  8. Python之路,第十三篇:Python入门与基础13

    python3   模块 模块 Module 概念: 模块是一个保护有一系统变量.函数.类等组成的程序组: 模块是一个文件,模块文件名通常以.py 结尾: 作用:让一些相关的变量,函数, 类等有逻辑的 ...

  9. flask中的模型

    1.什么是模型 模型,是根据数据库中表的结构而创建出来的class.每一张表对应到编程语言中,就是一个class表中的每一个列对应到编程语言中就class中的一个属性. 2.ORM的三大特征 1.数据 ...

  10. (22)Ajax的基本使用(实现登录功能和局部刷新以及防止跨站请求伪造攻击)

    Ajax的作用 前后端分离的项目,需要交互,就要通过Ajax来完成交互 AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”.即 ...