[loj2339]通道
类似于[loj2553]
对第一棵树边分治,对第二棵树建立虚树,并根据直径合并的性质来处理第三棵树(另外在第三棵树中计算距离需要使用dfs序+ST表做到$o(1)$优化)
总复杂度为$o(n\log^{2}n)$,可以通过
1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 100005
4 #define ll long long
5 #define pii pair<int,int>
6 #define vi vector<int>
7 #define fi first
8 #define se second
9 struct Edge{
10 int nex,to;
11 ll len;
12 };
13 int n;
14 ll ans,val[N];
15 ll calc(vi x,vi y);
16 ll dis3(int x,int y);
17 namespace T1{
18 int m,E,rt,x,y,head[N<<1],sz[N<<1],vis[N<<1];
19 ll z,dep[N<<1];
20 vi v,vx,vy;
21 vector<pair<int,ll> >e[N<<1];
22 Edge edge[N<<2];
23 void add(int x,int y,ll z){
24 edge[E]=Edge{head[x],y,z};
25 head[x]=E++;
26 }
27 void dfs(int k,int fa,ll s){
28 dep[k]=s;
29 for(int i=head[k];i!=-1;i=edge[i].nex)
30 if (edge[i].to!=fa)dfs(edge[i].to,k,s+edge[i].len);
31 v.clear();
32 for(int i=head[k];i!=-1;i=edge[i].nex)
33 if (edge[i].to!=fa)v.push_back(edge[i].to);
34 int lst=k;
35 for(int i=0;i+2<v.size();i++){
36 e[lst].push_back(make_pair(v[i],dep[v[i]]-dep[k]));
37 e[lst].push_back(make_pair(++m,0));
38 lst=m;
39 }
40 if (v.size()){
41 e[lst].push_back(make_pair(v.back(),dep[v.back()]-dep[k]));
42 v.pop_back();
43 if (v.size())e[lst].push_back(make_pair(v.back(),dep[v.back()]-dep[k]));
44 }
45 }
46 void build(){
47 m=n;
48 memset(head,-1,sizeof(head));
49 for(int i=1;i<n;i++){
50 scanf("%d%d%lld",&x,&y,&z);
51 add(x,y,z),add(y,x,z);
52 }
53 dfs(1,0,0);
54 E=0;
55 memset(head,-1,sizeof(head));
56 for(int i=1;i<=m;i++)assert(e[i].size()<=2);
57 for(int i=1;i<=m;i++)
58 for(int j=0;j<e[i].size();j++){
59 add(i,e[i][j].fi,e[i][j].se);
60 add(e[i][j].fi,i,e[i][j].se);
61 }
62 }
63 void get_sz(int k,int fa){
64 sz[k]=1;
65 for(int i=head[k];i!=-1;i=edge[i].nex)
66 if ((!vis[i>>1])&&(edge[i].to!=fa)){
67 get_sz(edge[i].to,k);
68 sz[k]+=sz[edge[i].to];
69 }
70 }
71 void get_rt(int k,int fa,int s){
72 for(int i=head[k];i!=-1;i=edge[i].nex)
73 if ((!vis[i>>1])&&(edge[i].to!=fa)){
74 get_rt(edge[i].to,k,s);
75 if ((s<=3*sz[edge[i].to]+1)&&(3*sz[edge[i].to]<=(s+1<<1)))rt=(i>>1);
76 }
77 }
78 void get_v(vi &v,int k,int fa,ll s){
79 if (k<=n){
80 val[k]=s;
81 v.push_back(k);
82 }
83 for(int i=head[k];i!=-1;i=edge[i].nex)
84 if ((!vis[i>>1])&&(edge[i].to!=fa))get_v(v,edge[i].to,k,s+edge[i].len);
85 }
86 void divide(int k){
87 get_sz(k,0);
88 if (sz[k]==1)return;
89 get_rt(k,0,sz[k]);
90 k=rt,vis[k]=1;
91 vx.clear(),vy.clear();
92 get_v(vx,edge[k<<1].to,0,0);
93 get_v(vy,edge[(k<<1)|1].to,0,0);
94 ans=max(ans,calc(vx,vy)+edge[k<<1].len);
95 divide(edge[k<<1].to);
96 divide(edge[(k<<1)|1].to);
97 }
98 };
99 namespace T2{
100 int E,x,y,head[N],dfn[N],sh[N],f[N][20],st[N];
101 ll z,ans,dep[N];
102 pii mx[N][2];
103 vi v0,v,e[N];
104 Edge edge[N<<1];
105 bool cmp(int x,int y){
106 return dfn[x]<dfn[y];
107 }
108 void add(int x,int y,ll z){
109 edge[E]=Edge{head[x],y,z};
110 head[x]=E++;
111 }
112 int lca(int x,int y){
113 if (sh[x]<sh[y])swap(x,y);
114 for(int i=19;i>=0;i--)
115 if (sh[f[x][i]]>=sh[y])x=f[x][i];
116 if (x==y)return x;
117 for(int i=19;i>=0;i--)
118 if (f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
119 return f[x][0];
120 }
121 void dfs(int k,int fa,int s1,ll s2){
122 dfn[k]=++dfn[0],sh[k]=s1,dep[k]=s2;
123 f[k][0]=fa;
124 for(int i=1;i<20;i++)f[k][i]=f[f[k][i-1]][i-1];
125 for(int i=head[k];i!=-1;i=edge[i].nex)
126 if (edge[i].to!=fa)dfs(edge[i].to,k,s1+1,s2+edge[i].len);
127 }
128 void build(){
129 memset(head,-1,sizeof(head));
130 for(int i=1;i<n;i++){
131 scanf("%d%d%lld",&x,&y,&z);
132 add(x,y,z),add(y,x,z);
133 }
134 dfs(1,1,0,0);
135 }
136 void build(vi v0){
137 bool flag=0;
138 for(int i=0;i<v0.size();i++)
139 if (v0[i]==1)flag=1;
140 if (!flag){
141 v0.push_back(1);
142 v.push_back(1);
143 }
144 sort(v0.begin(),v0.end(),cmp);
145 st[0]=st[1]=1;
146 for(int i=1;i<v0.size();i++){
147 int k=lca(v0[i],st[st[0]]);
148 while ((st[0]>1)&&(dfn[st[st[0]-1]]>=dfn[k])){
149 e[st[st[0]-1]].push_back(st[st[0]]);
150 st[0]--;
151 }
152 if (k!=st[st[0]]){
153 v.push_back(k);
154 e[k].push_back(st[st[0]]);
155 st[st[0]]=k;
156 }
157 st[++st[0]]=v0[i];
158 }
159 while (st[0]>1){
160 e[st[st[0]-1]].push_back(st[st[0]]);
161 st[0]--;
162 }
163 }
164 ll merge_ans(pii x,pii y){
165 return max(max(dis3(x.fi,y.fi),dis3(x.fi,y.se)),max(dis3(x.se,y.fi),dis3(x.se,y.se)));
166 }
167 pii merge(pii x,pii y){
168 pii ans=x;
169 if (dis3(y.fi,y.se)>dis3(ans.fi,ans.se))ans=y;
170 if (dis3(x.fi,y.fi)>dis3(ans.fi,ans.se))ans=make_pair(x.fi,y.fi);
171 if (dis3(x.fi,y.se)>dis3(ans.fi,ans.se))ans=make_pair(x.fi,y.se);
172 if (dis3(x.se,y.fi)>dis3(ans.fi,ans.se))ans=make_pair(x.se,y.fi);
173 if (dis3(x.se,y.se)>dis3(ans.fi,ans.se))ans=make_pair(x.se,y.se);
174 return ans;
175 }
176 void dfs(int k){
177 for(int i=0;i<e[k].size();i++){
178 dfs(e[k][i]);
179 ans=max(ans,merge_ans(mx[k][0],mx[e[k][i]][1])-(dep[k]<<1));
180 ans=max(ans,merge_ans(mx[k][1],mx[e[k][i]][0])-(dep[k]<<1));
181 mx[k][0]=merge(mx[k][0],mx[e[k][i]][0]);
182 mx[k][1]=merge(mx[k][1],mx[e[k][i]][1]);
183 }
184 }
185 ll calc(vi vx,vi vy){
186 ans=0,v0.clear();
187 for(int i=0;i<vx.size();i++)v0.push_back(vx[i]);
188 for(int i=0;i<vy.size();i++)v0.push_back(vy[i]);
189 for(int i=0;i<v0.size();i++)val[v0[i]]+=dep[v0[i]];
190 v=v0,build(v0);
191 for(int i=0;i<v.size();i++)mx[v[i]][0]=mx[v[i]][1]=make_pair(-1,-1);
192 for(int i=0;i<vx.size();i++)mx[vx[i]][0]=make_pair(vx[i],vx[i]);
193 for(int i=0;i<vy.size();i++)mx[vy[i]][1]=make_pair(vy[i],vy[i]);
194 dfs(1);
195 for(int i=0;i<v.size();i++)e[v[i]].clear();
196 return ans;
197 }
198 };
199 namespace T3{
200 int m,E,x,y,lg[N<<1],head[N],pos[N];
201 ll z,ans,dep[N<<1],f[N<<1][20];
202 Edge edge[N<<1];
203 void add(int x,int y,ll z){
204 edge[E]=Edge{head[x],y,z};
205 head[x]=E++;
206 }
207 ll get_min(int x,int y){
208 int m=lg[y-x+1];
209 return min(f[x][m],f[y-(1<<m)+1][m]);
210 }
211 ll dis(int x,int y){
212 x=pos[x],y=pos[y];
213 if (x>y)swap(x,y);
214 return dep[x]+dep[y]-(get_min(x,y)<<1);
215 }
216 void dfs(int k,int fa,ll s){
217 dep[++m]=s,pos[k]=m;
218 for(int i=head[k];i!=-1;i=edge[i].nex)
219 if (edge[i].to!=fa){
220 dfs(edge[i].to,k,s+edge[i].len);
221 dep[++m]=s;
222 }
223 }
224 void build(){
225 memset(head,-1,sizeof(head));
226 for(int i=1;i<n;i++){
227 scanf("%d%d%lld",&x,&y,&z);
228 add(x,y,z),add(y,x,z);
229 }
230 dfs(1,0,0);
231 lg[0]=-1;
232 for(int i=1;i<=m;i++)lg[i]=lg[i>>1]+1;
233 for(int i=m;i;i--){
234 f[i][0]=dep[i];
235 for(int j=1;j<20;j++)f[i][j]=min(f[i][j-1],f[min(i+(1<<j-1),m)][j-1]);
236 }
237 }
238 };
239 ll calc(vi vx,vi vy){
240 return T2::calc(vx,vy);
241 }
242 ll dis3(int x,int y){
243 if ((x<0)||(y<0))return -1e18;
244 return val[x]+val[y]+T3::dis(x,y);
245 }
246 int main(){
247 scanf("%d",&n);
248 T1::build();
249 T2::build();
250 T3::build();
251 T1::divide(1);
252 printf("%lld\n",ans);
253 return 0;
254 }
[loj2339]通道的更多相关文章
- 【loj2339】【WC2018】通道
题目 三棵带边权的树,求 \[ dis1(u,v) + dis2(u,v) + dis3(u,v) \] 的最大值 \(1 \le n \le 10^5\) 题解 对\(T_1\)做边分治,把分治边的 ...
- Paypal开发中遇到请求被中止: 未能创建 SSL/TLS 安全通道及解决方案
最近在基于ASP.NET上开发了Paypal支付平台,在ASP.NET开发的过程中没有遇到这个问题,但是引用到MVC开发模式中的时候就出现了"未能创建 SSL/TLS 安全通道及解决方案&q ...
- JAVA NIO Socket通道
DatagramChannel和SocketChannel都实现定义读写功能,ServerSocketChannel不实现,只负责监听传入的连接,并建立新的SocketChannel,本身不传输数 ...
- 学习 opencv---(4) 分离颜色通道 && 多通道混合
上篇文章中我们讲到了使用addWeighted函数进行图像混合操作,以及将ROI和addWeighted函数结合起来使用,对指定区域进行图像混合操作. 而为了更好地观察一些图像材料的特征,有时需要对R ...
- 关于QImage提取单色通道方法(vector)
转载请标明处: 作者:微微苏荷 本文地址:关于QImage提取单色通道方法(vector) 近日,用QT和mxnet结合做一个图像识别的demo.遇到需要把图片从QImage转为vector单色分离的 ...
- 基于暗通道优先算法的去雾应用(Matlab/C++)
基于暗通道优先的单幅图像去雾算法(Matlab/C++) 算法原理: 参见论文:Single Image Haze Removal Using Dark Channel Pri ...
- Java NIO4:Socket通道
Socket通道 上文讲述了通道.文件通道,这篇文章来讲述一下Socket通道,Socket通道与文件通道有着不一样的特征,分三点说: 1.NIO的Socket通道类可以运行于非阻塞模式并且是可选择的 ...
- Java NIO3:通道和文件通道
通道是什么 通道式(Channel)是java.nio的第二个主要创新.通道既不是一个扩展也不是一项增强,而是全新的.极好的Java I/O示例,提供与I/O服务的直接连接.Channel用于在字节缓 ...
- IO通道
本文原创,转载需标明原处. 通道,主要负责传输数据,相当于流,但流只能是输入或输出类型中的其一,而通道则可以兼并二者. 通道的基类是:Channel boolean isOpen() void clo ...
随机推荐
- 【Docker】(9)---每天5分钟玩转 Docker 容器技术之镜像
镜像是 Docker 容器的基石,容器是镜像的运行实例,有了镜像才能启动容器.为什么我们要讨论镜像的内部结构? 如果只是使用镜像,当然不需要了解,直接通过 docker 命令下载和运行就可以了. 但如 ...
- Linux7安装redis6
首先下载软件包并解压 cd /opt wget https://download.redis.io/releases/redis-6.2.5.tar.gz tar -zxvf redis-6.2.5. ...
- SphereEx 登陆 ApacheCon Asia|依托 ShardingSphere 可插拔架构体系打造数据应用完整生态
2021 年 8 月 8 日,ApacheCon 首次亚洲大会于线上正式闭幕.作为久负盛名的开源盛宴,本届 ApacheCon Asia 受到了海内外众多开源领域人士的关注. 作为 Apache 软件 ...
- WIN10下的VMware与Docker冲突的解决方案
VMARE版本升级到15.5以上 WIN10升级到2004版本以上 Hyper-V为开启状态
- Vuls 漏洞扫描工具部署及效果展示
Vuls 漏洞扫描工具部署及效果展示 介绍 Vuls根据NVD,OVAL等数据对主流Linux系统进行扫描,并具有完善的报告. 支持系统 Distribution Release Alpine 3.3 ...
- Java(35)IO特殊操作流&Properties集合
作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15228454.html 博客主页:https://www.cnblogs.com/testero ...
- ubuntu修改软件源的方法
最快方法--替换法 刚安装好的ubutun,打开source.list后,用vim替换的方法将所有的us提付出替换为 cn,然后保存退出,更新即可. # vim /etc/apt/source.lis ...
- 2021能源PWN wp
babyshellcode 这题考无write泄露,write被沙盒禁用时,可以考虑延时盲注的方式获得flag,此exp可作为此类型题目模版,只需要修改部分参数即可,详细见注释 from pwn im ...
- 基于Apache Hudi 的CDC数据入湖
作者:李少锋 文章目录: 一.CDC背景介绍 二.CDC数据入湖 三.Hudi核心设计 四.Hudi未来规划 1. CDC背景介绍 首先我们介绍什么是CDC?CDC的全称是Change data Ca ...
- sql递归查询部门数据
1 with cte as 2 ( 3 select a.DepartCode,a.DepartName,a.ParentDepartCode from tbDeparts a where Paren ...