[loj2339]通道
类似于
对第一棵树边分治,对第二棵树建立虚树,并根据直径合并的性质来处理第三棵树(另外在第三棵树中计算距离需要使用dfs序+ST表做到$o(1)$优化)
总复杂度为$o(n\log^{2}n)$,可以通过
1 #include2 using namespace std; 3 #define N 100005 4 #define ll long long 5 #define pii pair 6 #define vi vector 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 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 ){ 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 ){ 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 ){ 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 ){ 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 ) 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 ){ 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 ){ 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 )v0.push_back(vx[i]); 188 for(int i=0;i )v0.push_back(vy[i]); 189 for(int i=0;i dep[v0[i]]; 190 v=v0,build(v0); 191 for(int i=0;i 0]=mx[v[i]][1]=make_pair(-1,-1); 192 for(int i=0;i 0]=make_pair(vx[i],vx[i]); 193 for(int i=0;i 1]=make_pair(vy[i],vy[i]); 194 dfs(1); 195 for(int i=0;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< 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 ){ 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< 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 }