题目描述

一个人有很多的影子,新的旧的,他们不断消失重来。学者的影子在他苍白色的精神图景里成为了$n$个黑色的点,他们伸长的触手交叉形成了一颗黑色的树。假使每个影子点拥有一个权值$d_i$,黑色的树边也有一个权值$w_i$,对于一条黑色树的路径,令路径上所有影子点权值$d_i$的最小值为${min}_d$,路径上所有树边权值$w_i$的总和为$sum_w$,则该条路径的总权值为${min}_d\times sum_w$。路径的起点和终点可以是黑色树中的任意影子点,且路径中不能出现重复的影子点。
现在学者需要知道这棵黑色树里所有路径总权值中的最大值为多少


输入格式

第一行输入一个整数$T$,表示数据组数
每组数据第一行一个正整数$n$,表示影子点总数
之后$n$个整数,表示每个影子点的权值
之后$n-1$行,每行三个整数$u,v,w$表示一条连接$u,v$且权值为$w$的树边。数据保证不会出现重边,且一定构成树结构


输出格式

一共$T$行,表示当前这组数据的答案


样例

样例输入:

1
3
1 2 3
1 2 1
1 3 2

样例输出:

3


数据范围与提示

样例解释:

总权值最大的路径是$2\rightarrow 1\rightarrow 3$,${min}_d$为$min(1,2,3)=1$,${sum}_w$为$sum(1,2)=3$,因此答案为$1\times 3=3$。

数据范围:

对于$100\%$的数据$1\leqslant T\leqslant 10,1\leqslant n\leqslant {10}^5,1\leqslant d_i\leqslant {10}^9,1\leqslant u,v\leqslant n,1\leqslant w_i\leqslant {10}^9$
其中$35\%$的数据$1\leqslant n\leqslant 100$
其中最多有$50\%$的数据保证${10}^4\leqslant n\leqslant {10}^5$


题解

再一次没有打正解,显然正解是点分治。

然而我用的是比较玄学的并查集。

首先,将所有的点权从大到小排序,于将当前点和与其相连的所有点依次合并到一个集合中。

并查集维护当前集合中的最长路径长度和对应的两个端点。

保证当前这个点是并查集中最大的点,这样它肯定对$min_d$没有贡献。

那么,合并两个集合后集合的最长路分为两种情况:

  $\alpha.$其中一个集合的最长路。

  $\beta.$两个集合的最长路的端点相互连接。

这里就需要用到$LCA$了。

每次合并并查集之后用当前点的权值乘以最长路的总长度来更新最优结果即可。即使这个点不在当前合并后的集合的最长路上也是没有问题的,因为如果这样的话,必然已经在之前得到了对应的结果,这次合并不会对最终结果产生影响。

时间复杂度:$\Theta(n\log n)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
struct rec{int nxt,to,w;}e[200001];
int head[100001],cnt;
int n;
int f[100001],lft[100001],rht[100001],rk[100001];
int fa[100001][21],depth[100001];
long long dis[100001],len[100001];
pair<int,int> d[100001];
long long ans;
void pre_work()
{
memset(len,0,sizeof(len));
memset(head,0,sizeof(head));
memset(depth,0,sizeof(depth));
ans=cnt=0;
for(int i=1;i<=n;i++)f[i]=lft[i]=rht[i]=i;
}
void add(int x,int y,int w)
{
e[++cnt].nxt=head[x];
e[cnt].to=y;
e[cnt].w=w;
head[x]=cnt;
}
int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
void dfs(int x)
{
for(int i=head[x];i;i=e[i].nxt)
{
if(depth[e[i].to])continue;
depth[e[i].to]=depth[x]+1;
fa[e[i].to][0]=x;
for(int j=1;j<=20;j++)
fa[e[i].to][j]=fa[fa[e[i].to][j-1]][j-1];
dis[e[i].to]=dis[x]+e[i].w;
dfs(e[i].to);
}
}
int LCA(int x,int y)
{
int minn=1<<30;
if(depth[x]>depth[y])swap(x,y);
for(int i=20;~i;i--)
if(depth[fa[y][i]]>=depth[x])
y=fa[y][i];
if(x==y)return x;
for(int i=20;~i;i--)
if(fa[x][i]!=fa[y][i])
{
x=fa[x][i];
y=fa[y][i];
}
return fa[x][0];
}
long long get_dis(int x,int y){return dis[x]+dis[y]-(dis[LCA(x,y)]<<1);}
int main()
{
int T;scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
pre_work();
for(int i=1;i<=n;i++)
{
int x;scanf("%d",&x);
d[i]=make_pair(x,i);
}
sort(d+1,d+n+1,greater<pair<int,int> >());
for(int i=1;i<n;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
depth[1]=1;
dfs(1);
for(int i=1;i<=n;i++)rk[d[i].second]=i;
for(int i=1;i<=n;i++)
{
for(int j=head[d[i].second];j;j=e[j].nxt)
{
int to=find(e[j].to);
if(rk[d[i].second]<rk[to])continue;
len[0]=len[d[i].second],lft[0]=lft[d[i].second],rht[0]=rht[d[i].second];
if(len[to]>len[0]){len[0]=len[to];lft[0]=lft[to];rht[0]=rht[to];}
if((dis[0]=get_dis(lft[d[i].second],lft[to]))>len[0]){len[0]=dis[0];lft[0]=lft[d[i].second];rht[0]=lft[to];}
if((dis[0]=get_dis(rht[d[i].second],rht[to]))>len[0]){len[0]=dis[0];lft[0]=rht[d[i].second];rht[0]=rht[to];}
if((dis[0]=get_dis(lft[d[i].second],rht[to]))>len[0]){len[0]=dis[0];lft[0]=lft[d[i].second];rht[0]=rht[to];}
if((dis[0]=get_dis(rht[d[i].second],lft[to]))>len[0]){len[0]=dis[0];lft[0]=rht[d[i].second];rht[0]=lft[to];}
f[to]=d[i].second;lft[d[i].second]=lft[0];rht[d[i].second]=rht[0];len[d[i].second]=len[0];
}
ans=max(ans,len[d[i].second]*d[i].first);
}
printf("%lld\n",ans);
}
return 0;
}

rp++

[CSP-S模拟测试]:影子(并查集+LCA)的更多相关文章

  1. hdu 2874 Connections between cities (并查集+LCA)

    Connections between cities Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (J ...

  2. hdu6074[并查集+LCA+思维] 2017多校4

    看了标答感觉思路清晰了许多,用并查集来维护全联通块的点数和边权和. 用另一个up[]数组(也是并查集)来保证每条边不会被重复附权值,这样我们只要将询问按权值从小到大排序,一定能的到最小的边权和与联通块 ...

  3. [CSP-S模拟测试]:Dash Speed(线段树+并查集+LCA)

    题目描述 比特山是比特镇的飙车圣地.在比特山上一共有$n$个广场,编号依次为$1$到$n$,这些广场之间通过$n−1$条双向车道直接或间接地连接在一起,形成了一棵树的结构. 因为每条车道的修建时间以及 ...

  4. Gym 100814C Connecting Graph 并查集+LCA

    Description standard input/output Statements Alex is known to be very clever, but Walter does not be ...

  5. Network-POJ3694并查集+LCA

    Network Time Limit: 5000MS   Memory Limit: 65536K       Description A network administrator manages ...

  6. [并查集+LCA USACO18OPEN ] Disruption

    https://www.luogu.org/problemnew/show/P4374 一看这道题就是一个妙题,然后题解什么树链剖分...珂朵莉树... 还不如并查集来的实在!我们知道并查集本来就是路 ...

  7. Mobile Phone Network CodeForces - 1023F(并查集lca+修改环)

    题意: 就是有几个点,你掌控了几条路,你的商业对手也掌控了几条路,然后你想让游客都把你的所有路都走完,那么你就有钱了,但你又想挣的钱最多,真是的过分..哈哈 游客肯定要对比一下你的对手的路 看看那个便 ...

  8. HDU6074 Phone Call (并查集 LCA)

    Phone Call Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)Tota ...

  9. 习题:过路费(kruskal+并查集+LCA)

    过路费  [问题描述]在某个遥远的国家里,有 n 个城市.编号为 1,2,3,…,n.这个国家的政府修 建了 m 条双向道路,每条道路连接着两个城市.政府规定从城市 S 到城市 T 需 要收取的过路费 ...

随机推荐

  1. LOJ 2721 「NOI2018」屠龙勇士——扩展中国剩余定理

    题目:https://loj.ac/problem/2721 1.注意别一输入 p[ i ] 就 a[ i ] %= p[ i ] ,因为在 multiset 里找的时候还需要真实值. 2.注意用 m ...

  2. Codeforces Round #506 (Div. 3) E

    Codeforces Round #506 (Div. 3) E dfs+贪心 #include<bits/stdc++.h> using namespace std; typedef l ...

  3. Design:设计(活动)百科

    ylbtech-Design:设计(活动)百科 设计是把一种设想通过合理的规划.周密的计划.通过各种感觉形式传达出来的过程.人类通过劳动改造世界,创造文明,创造物质财富和精神财富,而最基础.最主要的创 ...

  4. Unzip 解压报错

      $ jar xvf pcre-8.10.zip   如果出现 jar:Command not found 要用yum下载 $ yum -y install java-1.6.0-openjdk-d ...

  5. selenium和phantomjs,完成豆瓣音乐排行榜的内容爬取

    代码要多敲 注释要清晰 哪怕再简单 #使用selenium和phantomjs,完成豆瓣音乐排行榜的内容爬取 #地址:https://music.douban.com/chart #导入需要的模块 f ...

  6. “希希敬敬对”队软件工程第九次作业-beta冲刺第四次随笔

    “希希敬敬对”队软件工程第九次作业-beta冲刺第四次随笔 队名:  “希希敬敬对” 龙江腾(队长) 201810775001 杨希                   201810812008 何敬 ...

  7. [fW]中断处理函数数组interrupt[]初始化

    中断处理函数数组interrupt[]初始化 2011-05-13 15:51:40 分类: LINUX 在系统初始化期间,trap_init()函数将对中断描述符表IDT进行第二次初始化(第一次只是 ...

  8. 下载Spring各个版本的jar包

    网址:https://repo.spring.io/webapp/#/artifacts/browse/tree/General/libs-release-local/org/springframew ...

  9. SAP Material Type on Classification Tree(ClassMaster management)

    SAP Material Type on Classification Tree(ClassMaster management) 1. Classification Tree 是 luxottica ...

  10. 如何减少代码中的if-else嵌套

    实际项目中,往往有大量的if-else语句进行各种逻辑校验,参数校验等等,大量的if-else,语句使代码变得臃肿且不好维护,本篇文章结合我自己的经验,就减少if-else语句给出以下几种方案,分别适 ...