1 条题解
-
0

#include <cstdio> #include <vector> #include <iostream> using namespace std; const int M = 100005; #define int long long const int inf = 1e18; int read() { int x=0,f=1;char c; while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;} while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();} return x*f; } int T,n,m,k,tot,f[M],fa[M][20];vector<int> b[M]; int lg[M],dep[M],dis[M],dfn[M],dp[M][20]; int ans,cnt,rt[M],ls[M*40],rs[M*40]; struct node{int x,y;}tmp; struct tree{node a,b;}o,zxy,t[M*40]; //zxy:use to make a clear struct edge{int v,c,next;}e[M<<1]; //O(nlogn)-O(1) lca void dfs(int u,int p)//initially dfs { dp[++m][0]=u;dfn[u]=m; fa[u][0]=p;dep[u]=dep[p]+1; for(int i=1;i<20;i++) fa[u][i]=fa[fa[u][i-1]][i-1]; for(int i=f[u];i;i=e[i].next) { int v=e[i].v,c=e[i].c; if(v==p) continue; dis[v]=dis[u]+c;dfs(v,u); dp[++m][0]=u; } } int Min(int x,int y) { return dep[x]<dep[y]?x:y; } void init()//st-table initializion { for(int i=2;i<=m;i++) lg[i]=lg[i>>1]+1; for(int j=1;(1<<j)<=m;j++) for(int i=1;i+(1<<j)-1<=m;i++) dp[i][j]=Min(dp[i][j-1],dp[i+(1<<j-1)][j-1]); } int lca(int l,int r)//O(1) lca { l=dfn[l];r=dfn[r]; if(l>r) swap(l,r); int k=lg[r-l+1]; return Min(dp[l][k],dp[r-(1<<k)+1][k]); } int jump(int x,int y)//the first point of x { for(int i=19;i>=0;i--) if(dep[fa[x][i]]>dep[y]) x=fa[x][i]; return x; } int getd(int u,int v) { return dis[u]+dis[v]-2*dis[lca(u,v)]; } //segment-tree merge int upd(int &mx,node u,node v) { if(!u.x || !v.x) return 0; int c=u.y+v.y+getd(u.x,v.x); if(c>mx) {mx=c;return 1;} return 0; } int comb(tree &s,tree u,tree v) { int ret=0,mx=-inf; //must consider the cases below if(!u.a.x && !u.a.y) {s=v;return -inf;} if(!v.a.x && !v.a.y) {s=u;return -inf;} if(upd(mx,u.a,v.a)) s=tree{u.a,v.a}; if(upd(mx,u.a,v.b)) s=tree{u.a,v.b}; if(upd(mx,u.b,v.a)) s=tree{u.b,v.a}; if(upd(mx,u.b,v.b)) s=tree{u.b,v.b}; ret=mx; if(upd(mx,u.a,u.b)) s=tree{u.a,u.b}; if(upd(mx,v.a,v.b)) s=tree{v.a,v.b}; return ret; } void up(int x) { if(!ls[x]) {t[x]=t[rs[x]];return ;} if(!rs[x]) {t[x]=t[ls[x]];return ;} comb(t[x],t[ls[x]],t[rs[x]]); } void ins(int &x,int l,int r,int id) { if(!x) x=++cnt; if(l==r) {t[x].a=tmp;return ;} int mid=(l+r)>>1; if(mid>=id) ins(ls[x],l,mid,id); else ins(rs[x],mid+1,r,id); up(x); } void del(int &x,int l,int r,int id) { if(l==r) {t[x]=zxy;return ;} int mid=(l+r)>>1; if(mid>=id) del(ls[x],l,mid,id); else del(rs[x],mid+1,r,id); up(x); } int merge(int x,int y) { if(!x || !y) return x|y; comb(t[x],t[x],t[y]); ls[x]=merge(ls[x],ls[y]); rs[x]=merge(rs[x],rs[y]); return x; } void dfs2(int u) { for(int i=f[u];i;i=e[i].next) { int v=e[i].v; if(v==fa[u][0]) continue; dfs2(v); ans=max(ans,comb(o,t[rt[u]],t[rt[v]])-2*dis[u]); rt[u]=merge(rt[u],rt[v]); } for(int v:b[u]) del(rt[u],1,k,v); } void work() { n=read();ans=-inf; for(int i=1;i<n;i++) { int u=read(),v=read(),c=read(); e[++tot]=edge{v,c,f[u]},f[u]=tot; e[++tot]=edge{u,c,f[v]},f[v]=tot; } dfs(1,0);init(); //handle the queries node emp;k=read(); for(int i=1;i<=k;i++) { int u=read(),v=read(),c=read(),d=getd(u,v); int x=lca(u,v),p=jump(u,x),q=jump(v,x); if(u!=x) { tmp=node{v,d-2*c+dis[u]}; ans=max(ans,comb(o,tree{tmp,emp},t[rt[u]])-2*dis[u]); ins(rt[u],1,k,i);b[p].push_back(i); } if(v!=x) { tmp=node{u,d-2*c+dis[v]}; ans=max(ans,comb(o,tree{tmp,emp},t[rt[v]])-2*dis[v]); ins(rt[v],1,k,i);b[q].push_back(i); } } dfs2(1); if(ans<=-inf) puts("F"); else printf("%lld\n",ans/2); //clear all // attention! for(int i=1;i<=n;i++) f[i]=rt[i]=dis[i]=dfn[i]=0,b[i].clear(); for(int i=1;i<=cnt;i++) ls[i]=rs[i]=0,t[i]=zxy; tot=cnt=n=m=k=0; } signed main() { T=read(); while(T--) work(); }
- 1
信息
- ID
- 2571
- 时间
- 8000ms
- 内存
- 512MiB
- 难度
- 10
- 标签
- 递交数
- 6
- 已通过
- 4
- 上传者