1 条题解

  • 0
    @ 2026-7-4 23:20:08

    #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
    上传者