题目描述

www.lydsy.com/JudgeOnline/upload/201805/day1(1).pdf

题解

首先来看这个我们要最大化的东西。

deep[u]+deep[v]-deep[lca(u,v)]-deep[lca(u',v')]

后面的那个东西看起来不太合群,我们可以把前后拆开。

deep[u]+deep[v]-deep[lca(u,v)]

我们发现这其实就是u到根的链和v到根的链的并。

然后它还等于(deep[u]+deep[v]+dis[u][v])/2

因为deep数组我们可以直接求出,所以我们就把一颗有根树上的问题放到了无根树上,也就是可以去掉lca的影响了。

然后考虑枚举第二颗树的LCA,那么一组合法的点应当在这个点的两颗不同的子树中。

然后对第一棵树边分,发现这颗边分树也是一颗二叉树,每个叶子结点代表原树上的一个点。

于是这题的做法来了,我们在dfs第二颗树的时候,像线段树合并一样合并边分树,因为不管叶子的情况下,每个节点都代表一条边,每条边连接着两个点。

这样我们对这个点记一个lans和rans分别代表左端点的最优答案和右端点的最优答案。

维护答案的形式为deep[x]+dis(x,edge)

合并的时候顺带计算答案。

注意,要考虑u和v重合的情况。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define inf 1e18
#define N 740009
using namespace std;
typedef long long ll;
ll lans[N*],rans[N*],ans,dis[N],deep[N][],nowdeep,val[N*];
int atp,size[N],sum,nowroot,root,ha,finaldep[N];
int fa[N*],ls[N*],rs[N*],tr[N*][],dian,T[N],n,id[N*];
bool jin[N<<];
inline ll rd(){
ll x=;char c=getchar();bool f=;
while(!isdigit(c)){if(c=='-')f=;c=getchar();}
while(isdigit(c)){x=(x<<)+(x<<)+(c^);c=getchar();}
return f?-x:x;
}
struct tu{
int head[N],tot;
struct edge{int n,to;ll l;}e[N<<];
void clear(){memset(head,,sizeof(head));tot=;}
inline void add(int u,int v,ll l){e[++tot].n=head[u];e[tot].to=v;head[u]=tot;e[tot].l=l;}
}E[];
struct node{int n,to;ll l;}e[N<<];
int head[N<<],tot=;
inline void add(int u,int v,ll l){
e[++tot].n=head[u];e[tot].to=v;head[u]=tot;e[tot].l=l;
e[++tot].n=head[v];e[tot].to=u;head[v]=tot;e[tot].l=l;
}
void dfs1(int u,int fa){
int now=;
for(int i=E[].head[u];i;i=E[].e[i].n)if(E[].e[i].to!=fa){
int v=E[].e[i].to;dis[v]=dis[u]+E[].e[i].l;
if(!now){add(u,v,E[].e[i].l);now=u;}
else{++atp;add(now,atp,);add(atp,v,E[].e[i].l);now=atp;}
dfs1(v,u);
}
}
void getroot(int u,int fa){
size[u]=;
for(int i=head[u];i;i=e[i].n)if(e[i].to!=fa&&!jin[i]){
int v=e[i].to;
getroot(v,u);
size[u]+=size[v];
if(max(size[v],sum-size[v])<nowroot){root=i;nowroot=max(size[v],sum-size[v]);ha=size[v];}
}
}
void getdeep(int u,int fa,int dep){
for(int i=head[u];i;i=e[i].n)if(e[i].to!=fa&&!jin[i]){
int v=e[i].to;
deep[v][dep]=deep[u][dep]+e[i].l;
getdeep(v,u,dep);
}
}
int solve(int u,int s,int dep){
if(s==){finaldep[u]=dep;return u;}
int now=++atp;
root=atp+;nowroot=atp;sum=s;
getroot(u,);
jin[root]=jin[root^]=;
int x=e[root].to,y=e[root^].to,xs=ha,ys=s-ha;val[atp]=e[root].l;
getdeep(x,y,dep);getdeep(y,x,dep);
fa[ls[now]=solve(x,xs,dep+)]=now;fa[rs[now]=solve(y,ys,dep+)]=now;
return now;
}
inline int ins(int x){
int now=x,pre=;
for(int i=finaldep[x];i;--i){
++dian;id[dian]=fa[now];lans[dian]=rans[dian]=-inf;
if(ls[fa[now]]==now)lans[dian]=dis[x]+deep[x][i-],tr[dian][]=pre;
if(rs[fa[now]]==now)rans[dian]=dis[x]+deep[x][i-],tr[dian][]=pre;
pre=dian;now=fa[now];
}
return dian;
}
inline int merge(int x,int y){
if(!x||!y)return x^y;
ans=max(ans,(lans[x]+rans[y]+val[id[x]])/-nowdeep);
ans=max(ans,(rans[x]+lans[y]+val[id[x]])/-nowdeep);
lans[x]=max(lans[x],lans[y]);rans[x]=max(rans[x],rans[y]);
tr[x][]=merge(tr[x][],tr[y][]);tr[x][]=merge(tr[x][],tr[y][]);
return x;
}
void dfs2(int u,int fa,ll d){
T[u]=ins(u);
ans=max(ans,dis[u]-d);
for(int i=E[].head[u];i;i=E[].e[i].n)if(E[].e[i].to!=fa){
int v=E[].e[i].to;
dfs2(v,u,d+E[].e[i].l);nowdeep=d;
T[u]=merge(T[u],T[v]);
}
}
int main(){
n=rd();int u,v;ll w;ans=-inf;
for(int i=;i<n;++i){u=rd();v=rd();w=rd();E[].add(u,v,w);E[].add(v,u,w);}
for(int i=;i<n;++i){u=rd();v=rd();w=rd();E[].add(u,v,w);E[].add(v,u,w);}
atp=n;dfs1(,);
solve(,atp,);
dfs2(,,);
printf("%lld\n",ans);
return ;
}

[CTSC2018]暴力写挂的更多相关文章

  1. [CTSC2018]暴力写挂——边分树合并

    [CTSC2018]暴力写挂 题面不错 给定两棵树,两点“距离”定义为:二者深度相加,减去两棵树上的LCA的深度(深度指到根节点的距离) 求最大的距离. 解决多棵树的问题就是降维了. 经典的做法是边分 ...

  2. [LOJ#2553][CTSC2018]暴力写挂

    [LOJ#2553][CTSC2018]暴力写挂 试题描述 temporaryDO 是一个很菜的 OIer .在 4 月,他在省队选拔赛的考场上见到了<林克卡特树>一题,其中 \(k = ...

  3. BZOJ5341: [Ctsc2018]暴力写挂

    BZOJ5341: [Ctsc2018]暴力写挂 https://lydsy.com/JudgeOnline/problem.php?id=5341 分析: 学习边分治. 感觉边分治在多数情况下都能用 ...

  4. BZOJ5341[Ctsc2018]暴力写挂——边分治+虚树+树形DP

    题目链接: CSTC2018暴力写挂 题目大意:给出n个点结构不同的两棵树,边有边权(有负权边及0边),要求找到一个点对(a,b)满足dep(a)+dep(b)-dep(lca)-dep'(lca)最 ...

  5. UOJ400/LOJ2553 CTSC2018 暴力写挂 边分治、虚树

    传送门--UOJ 传送门--LOJ 跟隔壁通道是一个类型的 要求的式子中有两个LCA,不是很方便,因为事实上在这种题目中LCA一般都是枚举的对象-- 第二棵树上的LCA显然是动不了的,因为没有其他的量 ...

  6. bzoj 5341: [Ctsc2018]暴力写挂

    Description Solution 边分治+边分树合并 这个题很多做法都是启发式合并的复杂度的,都有点卡 以前有个套路叫做线段树合并优化启发式合并,消掉一个 \(log\) 这个题思路类似,建出 ...

  7. 并不对劲的bzoj5341:loj2553:uoj400:p4565:[Ctsc2018]暴力写挂

    题目大意 有两棵\(n\)(\(n\leq366666\))个节点的树,\(T\)和\(T'\),有边权 \(dep(i)\)表示在\(T\)中\(i\)号点到\(1\)号点的距离,\(dep'(i) ...

  8. 题解 「CTSC2018暴力写挂」

    题目传送门 题目大意 给出两个大小为 \(n\) 的树,求出: \[\max\{\text{depth}(x)+\text{depth}(y)-\text{depth}(\text{LCA}(x,y) ...

  9. 【CTSC2018】暴力写挂(边分治,虚树)

    [CTSC2018]暴力写挂(边分治,虚树) 题面 UOJ BZOJ 洛谷 题解 发现第二棵树上的\(LCA\)的深度这玩意没法搞,那么枚举在第二棵树上的\(LCA\). 然后剩下的部分就是\(dep ...

随机推荐

  1. 安卓基础之通过Intent跳转Activity

    通过Intent跳转Activity   一.通过意图开启Activity的方式:   隐式意图:通过指定一组数据或者动作实现 Intent intent=new Intent(); intent.s ...

  2. Docker 镜像编排并部署SpringBoot应用

    Docker-compose是一个基于Docker的编排工具,所谓编排个人理解就是将不同的镜像通过配置,组成一个新的运行环境,官方定义是:Compose is a tool for defining ...

  3. 一个磁盘I/O故障导致的AlwaysOn FailOver 过程梳理和分析

    下面是我们在使用AlwaysOn过程中遇到的一个切换案例.这个案例发生在2014年8月,虽然时间相对久远了,但是对我们学习理解AlwaysOn的FailOver原理和过程还是很有帮助的.本次FailO ...

  4. jquery datatable 实例操作

    var dataTables = $(".table").dataTable({ data: d,//为ajax的值,没有直接用插件自带的请求数据方式,个人觉得data的方式好控制 ...

  5. Bootstrap -- 导航栏样式、分页样式、标签样式、徽章样式

    Bootstrap -- 导航栏样式.分页样式.标签样式.徽章样式 1. 使用图标的导航栏 使用导航栏样式: <!DOCTYPE html> <html> <head&g ...

  6. Scrapy案例02-腾讯招聘信息爬取

    目录 1. 目标 2. 网站结构分析 3. 编写爬虫程序 3.1. 配置需要爬取的目标变量 3.2. 写爬虫文件scrapy 3.3. 编写yield需要的管道文件 3.4. setting中配置请求 ...

  7. 一个小错误:error LNK2019: 无法解析的外部符号 "public: __thiscall Turtle::~Turtle(void)" (??1Turtle@@QAE@XZ),该符号在函数 _main 中被引用

    昨天在撸代码的时候遇到了一个十分蛋疼的错误 : 错误: 1>3.obj : error LNK2019: 无法解析的外部符号 "public: __thiscall Turtle::~ ...

  8. Python基础之协程

    阅读目录 一 引子 二 协程介绍 三 Greenlet模块 四 Gevent模块 引子 之前我们学习了线程.进程的概念,了解了在操作系统中 进程是资源分配的最小单位,线程是CPU调度的最小单位. 按道 ...

  9. 【Python 19】BMR计算器3.0(字符串分割与格式化输出)

    1.案例描述 基础代谢率(BMR):我们安静状态下(通常为静卧状态)消耗的最低热量,人的其他活动都建立在这个基础上. 计算公式: BMR(男) = (13.7*体重kg)+(5.0*身高cm)-(6. ...

  10. 5000量子位支持量子编程,D-Wave推出下一代量子计算平台计划

    5000量子位支持量子编程,D-Wave推出下一代量子计算平台计划 近日,全球量子商用化重要参与者 D-Wave 公司又有大动作:推出其5000量子比特量子计算的发展蓝图.D-Wave 下一代量子计算 ...