题解 \(by\;zj\varphi\)

一道并查集的题

对于它路径上点权,我们可以转化一下:对于一个点,它在哪些路径上是最小的点权

那么我们排个序,从大到小加入点,每回加入时,将这个点与它所相连的且权值比它大的点所在集合合并

那么这个新集合中,这个点的权值一定是最小的,所以求出这个集合的直径即可

对于这个新集合的直径,一定是由原来的集合的直径的端点组合而来的,或就直接是两个集合中直径大的那个

一共六种情况,枚举即可,复杂度可以做到 \(O(nlogn)\)

Code


#include<bits/stdc++.h>
#define ri register signed
#define p(i) ++i
using namespace std;
namespace IO{
char buf[1<<21],*p1=buf,*p2=buf;
#define gc() p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++
template<typename T>inline void read(T &x) {
ri f=1;x=0;register char ch=gc();
while(ch<'0'||ch>'9') {if (ch=='-') f=0;ch=gc();}
while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=gc();}
x=f?x:-x;
}
}
using IO::read;
namespace nanfeng{
#define cmax(x,y) ((x)>(y)?(x):(y))
#define cmin(x,y) ((x)>(y)?(y):(x))
#define FI FILE *IN
#define FO FILE *OUT
typedef long long ll;
static const int N=1e5+7;
int first[N],fa[N],w[N],head[N],st[N<<1][19],lg[N<<1],dep[N],p[N],ol,n,T,t=1;
ll dis[N],wl[N],ans;
struct edge{int v,nxt,w;}e[N<<1];
struct node{int x1,x2;}pnt[N];
inline void add(int u,int v,int w) {
e[t].v=v,e[t].w=w,e[t].nxt=first[u],first[u]=t++;
e[t].v=u,e[t].w=w,e[t].nxt=first[v],first[v]=t++;
}
int find(int x) {return fa[x]==x?x:fa[x]=find(fa[x]);}
void dfs(int x,int f) {
head[st[p(ol)][0]=x]=ol;
for (ri i(first[x]),v;i;i=e[i].nxt) {
if ((v=e[i].v)==f) continue;
dep[v]=dep[x]+1,dis[v]=dis[x]+e[i].w;
dfs(v,x);
st[p(ol)][0]=x;
}
}
inline void init_rmq() {
dfs(1,0);
int k=lg[ol];
for (ri j(1);j<=k;p(j)) {
ri len=1<<j;
for (ri i(1);i+len-1<=ol;p(i)) {
ri x1=st[i][j-1],x2=st[i+(1<<j-1)][j-1];
st[i][j]=dep[x1]<dep[x2]?x1:x2;
}
}
}
inline int Getlca(int u,int v) {
if (head[u]>head[v]) swap(u,v);
ri k=lg[head[v]-head[u]+1];
ri x1=st[head[u]][k],x2=st[head[v]-(1<<k)+1][k];
return dep[x1]<dep[x2]?x1:x2;
}
inline int cmp(int x,int y) {return w[x]>w[y];}
inline int main() {
// FI=freopen("nanfeng.in","r",stdin);
// FO=freopen("nanfeng.out","w",stdout);
for (ri i(2);i<N<<1;p(i)) lg[i]=lg[i>>1]+1;
read(T);
for (ri z(1);z<=T;p(z)) {
memset(first,0,sizeof(first));
memset(wl,0,sizeof(wl));
t=1,ans=ol=0;
read(n);
for (ri i(1);i<=n;p(i)) read(w[i]),fa[i]=p[i]=i,pnt[i].x1=pnt[i].x2=i;
for (ri i(1),u,v,ew;i<n;p(i)) read(u),read(v),read(ew),add(u,v,ew);
init_rmq();
sort(p+1,p+n+1,cmp);
for (ri i(1);i<=n;p(i)) {
ri cur=p[i];
// printf("%d %d ans=%lld\n",w[cur],cur,ans);
for (ri j(first[cur]),v;j;j=e[j].nxt) {
if (w[v=e[j].v]<w[cur]) continue;
ri r1=find(e[j].v),r2=find(cur);
ri r1x1=pnt[r1].x1,r1x2=pnt[r1].x2;
ri r2x1=pnt[r2].x1,r2x2=pnt[r2].x2;
ri l11=Getlca(r1x1,r2x1),l12=Getlca(r1x1,r2x2);
ri l21=Getlca(r1x2,r2x1),l22=Getlca(r1x2,r2x2);
ri nx1=r1x1,nx2=r1x2;
// if (cur==1) printf("in r2=%d nx1=%d nx2=%d %lld\n",r2,r2x1,r2x2,wl[r2]);
register ll res=wl[r1]; if (wl[r1]<wl[r2]) res=wl[r2],nx1=r2x1,nx2=r2x2; if (res<dis[r1x1]+dis[r2x1]-(dis[l11]<<1))
res=dis[r1x1]+dis[r2x1]-(dis[l11]<<1),nx1=r1x1,nx2=r2x1;
if (res<dis[r1x1]+dis[r2x2]-(dis[l12]<<1))
res=dis[r1x1]+dis[r2x2]-(dis[l12]<<1),nx1=r1x1,nx2=r2x2;
if (res<dis[r1x2]+dis[r2x1]-(dis[l21]<<1))
res=dis[r1x2]+dis[r2x1]-(dis[l21]<<1),nx1=r1x2,nx2=r2x1;
if (res<dis[r1x2]+dis[r2x2]-(dis[l22]<<1))
res=dis[r1x2]+dis[r2x2]-(dis[l22]<<1),nx1=r1x2,nx2=r2x2;
// res=max(res,di[r1x1]+dis[r2x1]-(dis[Getlca(r1x1,r2x1)]<<1));
// res=max(res,di[r1x1]+dis[r2x2]-(dis[Getlca(r1x1,r2x2)]<<1));
// res=max(res,di[r1x2]+dis[r2x1]-(dis[Getlca(r1x2,r2x1)]<<1));
// res=max(res,di[r1x2]+dis[r2x2]-(dis[Getlca(r1x2,r2x2)]<<1));
wl[fa[r1]=r2]=res;
ans=cmax(ans,res*w[cur]);
pnt[r2].x1=nx1,pnt[r2].x2=nx2;
// if (cur==1) printf("out r2=%d nx1=%d nx2=%d %lld\n",r2,r2x1,r2x2,wl[r2]);
// printf("w[%d]=%d %d %d res=%lld ans=%lld\n",cur,w[cur],nx1,nx2,res,ans);
}
// printf("%d %d ans=%lld\n",w[cur],cur,ans);
}
printf("%lld\n",ans);
}
return 0;
}
// #undef int
}
int main() {return nanfeng::main();}

NOIP 模拟 $15\; \text{影子}$的更多相关文章

  1. NOIP 模拟 $15\; \text{夜莺与玫瑰}$

    题解 一道很妙的题,让求对于一个矩阵中,两点相连成线,有多少条直线,他们的交集是有限集. 转化一下题目,发现水平和竖直的只有 \(n+m\) 条,而左斜和右斜的条数是相同的,所以我们只需求出左或右中的 ...

  2. NOIP 模拟 $15\; \rm \text{玫瑰花精}$

    题解 \(by\;zj\varphi\) 一道线段树题目 这道题可以通过维护一棵线段树,线段树上的每个节点维护 \(\rm l,r,len,p\) 分别表示这段区间最左边的花精,最右边的花精,被两只花 ...

  3. NOIP模拟 1

    NOIP模拟1,到现在时间已经比较长了.. 那天是6.14,今天7.18了 //然鹅我看着最前边缺失的模拟1,还是终于忍不住把它补上,为了保持顺序2345重新发布了一遍.. #   用  户  名   ...

  4. 20190725 NOIP模拟8

    今天起来就是虚的一批,然后7.15开始考试,整个前半个小时异常的困,然后一看题,T1一眼就看出了是KMP,但是完了,自己KMP的打法忘的一干二净,然后开始打T2,T2肝了一个tarjan点双就扔上去了 ...

  5. 2021.5.22 noip模拟1

    这场考试考得很烂 连暴力都没打好 只拿了25分,,,,,,,,好好总结 T1序列 A. 序列 题目描述 HZ每周一都要举行升旗仪式,国旗班会站成一整列整齐的向前行进. 郭神作为摄像师想要选取其中一段照 ...

  6. noip第15课作业

    1. 累加求和 给定n(1<=n<=100),用递归的方法计算1+2+3+4+5+......+(n-1)+n. 输入:一个大于等于1的整数. 输出:输出一个整数. [样例输入] 5 [样 ...

  7. NOIP模拟

    1.要选一个{1,2,...n}的子集使得假如a和b在所选集合里且(a+b)/2∈{1,2,...n}那么(a+b)/2也在所选集合里 f[i]=2*f[i-1]-f[i-2]+g[i] g[n]:选 ...

  8. NOIP模拟3

    期望得分:30+90+100=220 实际得分:30+0+10=40 T1智障错误:n*m是n行m列,硬是做成了m行n列 T2智障错误:读入三个数写了两个%d T3智障错误:数值相同不代表是同一个数 ...

  9. 7.22 NOIP模拟7

    又是炸掉的一次考试 T1.方程的解 本次考试最容易骗分的一道题,但是由于T2花的时间太多,我竟然连a+b=c都没判..暴力掉了40分. 首先a+b=c,只有一组解. 然后是a=1,b=1,答案是c-1 ...

随机推荐

  1. Kotlin Coroutine(协程): 一、样例

    @ 目录 前言 一.直接上例子 1.延时任务. 2.异步任务 3.并行任务: 4.定时任务: 总结 前言 你还在用 Hanlder + Message? 或者 AsyncTask? 你还在用 Rxja ...

  2. C#下通过wbemtest和WMI Code Cretor更加高效的访问WMI

    能找到这篇博客的,相信都是有操作WMI需求的了.但是不知道如何快速验证.并集成到C#来操作WMI.我们分为3步: ##第一步:官网(或跟硬件开发WMI的人沟通你需要的接口和参数定义,如果是和硬件开发的 ...

  3. ZooKeeper 分布式锁 Curator 源码 01:可重入锁

    前言 一般工作中常用的分布式锁,就是基于 Redis 和 ZooKeeper,前面已经介绍完了 Redisson 锁相关的源码,下面一起看看基于 ZooKeeper 的锁.也就是 Curator 这个 ...

  4. 续PA协商过程

    续PA协商过程 当sw3的接口恢复之后会发生2中情况. ①sw3的G0/0/2口先发BPDU ②sw3的G0/0/3口先发BPDU sw3先发送BPDU sw3和sw1的交互过程: sw3的2口恢复后 ...

  5. C语言:地址

    一切都是地址 C语言用变量来存储数据,用函数来定义一段可以重复使用的代码,它们最终都要放到内存中才能供 CPU 使用.数据和代码都以二进制的形式存储在内存中,计算机无法从格式上区分某块内存到底存储的是 ...

  6. C语言:3个数排序

    #include <stdio.h> int main() { int a,b,c,t; /*定义4个基本整型变量a.b.c.t*/ printf("Please input a ...

  7. Java基础00-分支语句6

    1. 流程控制 1.1 流程控制语句概述 1.2 流程控制语句分类 1.3 顺序结构 2. if语句 2.1 if语句格式1 适合一种情况的判断 执行流程图: 2.2 if语句格式2 适合两种情况的判 ...

  8. shell编程-ssh免交互批量分发公钥脚本

    脚本基本原理 1.控制端免交互创建秘钥和公钥: 1 ssh-keygen -t rsa -f /root/.ssh/id_rsa -N "" 2.免交互发送公钥 1 sshpass ...

  9. 自动化测试(1)selenium+python+chrome 连接测试

    环境准备: python版本:3.8.4 开发工具:pycharm 使用chrome和对应的webdriver http://npm.taobao.org/mirrors/chromedriver/ ...

  10. SAML 2.0简介(1)

    1.什么是SAML: SAML是Web浏览器用来通过安全令牌启用单点登录(SSO)的标准协议 2.优点: 跨多个应用程序管理用户身份和授权. 3.单点登录(SSO)是什么: 它使用户仅使用一组凭据(用 ...