rt,TLE on test 1。做法是考虑倒着做,然后维护每棵树的直径的两端,使用树上启发式合并,然后用倍增维护树上两点距离
#include <bits/stdc++.h>
#define fs first
#define sc second
using namespace std;
inline int read(){
int x=0,f=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=-1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+(ch&15);
return f*x;
}
int t,n,rt[100005],q,u,v,w,siz[100005],op[100005],tim[100005],dep[100005],f[100005][18];
long long dis[100005],res[100005],ans;
pair<int,pair<int,int> > e[100005];
vector<pair<int,int> > g[100005];
pair<int,int> zj[100005];
inline int lca(int x,int y){
if(dep[x]<dep[y]) swap(x,y);
while(dep[x]>dep[y]) x=f[x][(int)__lg(dep[x]-dep[y])];
if(x==y) return x;
for(int i=__lg(dep[x]);~i;i--)
if(f[x][i]^f[y][i])
x=f[x][i],y=f[y][i];
return f[x][0];
}
inline long long gdis(int x,int y){
int lc=lca(x,y);
return dis[x]+dis[y]-(dis[lc]<<1);
}
void dfs(int x,int fa,int root){
rt[x]=root,f[x][0]=fa,dep[x]=dep[fa]+1;
for(int i=1;i<=__lg(dep[x]);i++)
f[x][i]=f[f[x][i-1]][i-1];
for(int i=0;i<g[x].size();i++)
if(g[x][i].fs^fa)
dis[g[x][i].fs]=dis[x]+g[x][i].sc,dfs(g[x][i].fs,x,root);
}
inline void merge(int x){
int u=e[x].fs,v=e[x].sc.fs,w=e[x].second.second;
if(siz[rt[u]]<siz[rt[v]]) swap(u,v);
long long dis1=gdis(u,zj[rt[u]].fs),v1=zj[rt[u]].fs,dis2=gdis(v,zj[rt[v]].fs),v2=zj[rt[v]].fs,dis3,dis4,dis5;
g[u].push_back(e[x].sc),g[v].push_back(make_pair(e[x].fs,e[x].sc.sc));
dis3=gdis(u,zj[rt[u]].second);
if(dis3>dis1) dis1=dis3,v1=zj[rt[u]].sc;
dis3=gdis(v,zj[rt[v]].sc);
if(dis3>dis2) dis2=dis3,v2=zj[rt[v]].sc;
dis4=gdis(zj[rt[u]].fs,zj[rt[u]].sc);
dis5=gdis(zj[rt[v]].fs,zj[rt[v]].sc);
dis3=dis1+dis2+w;
if(dis3>=dis4&&dis3>=dis5) zj[rt[u]]=make_pair(v1,v2);
else if(dis4>=dis3&&dis4>=dis5);
else zj[rt[u]]=zj[rt[v]];
siz[rt[u]]+=siz[rt[v]],siz[rt[v]]=0;
// cerr<<x<<endl;
dis[v]=dis[u]+w,dfs(v,u,rt[u]);
ans=max(ans,max(dis3,max(dis4,dis5)));
}
signed main(){
t=read();
while(t--){
n=read(),q=read(),ans=0;
for(int i=1;i<n;i++) tim[i]=q+1,u=read(),v=read(),w=read(),e[i]=make_pair(u,make_pair(v,w));
// puts("-1");
for(int i=1;i<=q;i++)
op[i]=read(),tim[op[i]]=i;
for(int i=1;i<=n;i++) siz[i]=1,rt[i]=i,zj[i]=make_pair(i,i),dep[i]=1,dis[i]=0,f[i][0]=0,g[i].clear();
// puts("ccf");
for(int i=1;i<n;i++)
if(tim[i]==q+1)
merge(i);
res[q+1]=ans;
for(int i=q;i>1;i--)
merge(op[i]),res[i]=ans;
// for(int i=1;i<=n;i++)
// cout<<f[i][0]<<endl;
for(int i=2;i<=q+1;i++)
printf("%lld\n",res[i]);
}
return 0;
}