Luogu4220 [WC2018]通道

Luogu4220 [WC2018]通道

边分治

考虑如果是两棵树,对一棵树边分治,同时在另一棵树上建虚树统计答案,套路和[CTSC2018]暴力写挂相同。

一开始想不到好的办法,直接对第二棵树的虚树再次边分治,同时在第三棵树上建虚树,统计答案,时间复杂度\(O(n \log^2 n)\)

结果\(T\)飞了。

\(Code:\)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 100005
#define M 200005
#define ll long long
#define rint register int
#define il inline
using namespace std;
const int INF=1000000007;
const ll LINF=491919191919191919;
int n,x,y,gn;
ll z;
struct node
{
    int nxt,v;
    ll cost;
    il node (int Nxt=0,int D1=0,ll D2=0)
    {
        nxt=Nxt,v=D1,cost=D2;
    }
};
struct edge
{
    int tot=0,fr[N];
    node e[N << 1];
    il void add(int x,int y,ll z)
    {
        ++tot;
        e[tot]=node(fr[x],y,z),fr[x]=tot;
    }
}T1,T2,T3;
int lg2[N << 1];
struct ST
{
    int cnt,ct,dep[N],dfn[N],bg[N],st[N << 1][22];
    ll cdp[N];
    il int lca(int x,int y)
    {
        x=bg[x],y=bg[y];
        if (x>y)
            swap(x,y);
        int k=lg2[y-x+1];
        return (dep[st[x][k]]<dep[st[y-(1 << k)+1][k]])?st[x][k]:st[y-(1 << k)+1][k];
    }
    il ll dis(int x,int y)
    {
        return cdp[x]+cdp[y]-(cdp[lca(x,y)] << 1LL);
    }
}s2,s3;
int tot=1,fr[M];
node e[M << 1];
int rt,rtsz,s[N];
int sz[M],col[N],col2[N];
int c[2][N];
ll ans=-LINF,mx,kdp[M];
bool vis[M];
char buf[1 << 23],*p1=buf,*p2=buf,obuf[1 << 23],*O=obuf;
#define getchar() (p1==p2 && (p2=(p1=buf)+fread(buf,1,1 << 21,stdin),p1==p2)?EOF:*p1++)
il int iread()
{
	int s=0;
	char c=getchar();
	while (c<'0' || c>'9')
		c=getchar();
	while ('0'<=c && c<='9')
		s=(s << 1)+(s << 3)+(c^48),c=getchar();
	return s;
}
il ll lread()
{
	ll s=0;
	char c=getchar();
	while (c<'0' || c>'9')
		c=getchar();
	while ('0'<=c && c<='9')
		s=(s << 1)+(s << 3)+(c^48),c=getchar();
	return s;
}
template<typename T>
il T cmx(T x,T y)
{
    return (x>y)?x:y;
}
il void add(int x,int y,ll z)
{
    ++tot;
    e[tot]=node(fr[x],y,z),fr[x]=tot;
}
il void add_edge(int x,int y,ll z)
{
    add(x,y,z),add(y,x,z);
}
il void dfs1(int u,int F)
{
    int tt=0,lst;
    rint i=T1.fr[u];
    if (T1.e[i].v==F)
    	i=T1.e[i].nxt;
    while (i)
    {
        int v=T1.e[i].v;
        ll cost=T1.e[i].cost;
        i=T1.e[i].nxt;
        if (T1.e[i].v==F)
        	i=T1.e[i].nxt;
        ++tt;
        if (tt==1)
            add_edge(u,v,cost),lst=u; else
        if (i)
            ++gn,add_edge(lst,gn,0),add_edge(gn,v,cost),lst=gn; else
            add_edge(lst,v,cost);
        dfs1(v,u);
    }
}
il void dfs2(int u,int F)
{
    s2.dfn[++s2.cnt]=u,s2.st[++s2.ct][0]=u,s2.bg[u]=s2.ct;
    for (rint i=T2.fr[u];i;i=T2.e[i].nxt)
    {
        int v=T2.e[i].v;
        ll cost=T2.e[i].cost;
        if (v==F)
            continue;
        s2.cdp[v]=s2.cdp[u]+cost;
        s2.dep[v]=s2.dep[u]+1;
        dfs2(v,u);
        s2.st[++s2.ct][0]=u;
    }
}
il void dfs3(int u,int F)
{
    s3.dfn[++s3.cnt]=u,s[u]=s3.cnt,s3.st[++s3.ct][0]=u,s3.bg[u]=s3.ct;
    for (rint i=T3.fr[u];i;i=T3.e[i].nxt)
    {
        int v=T3.e[i].v;
        ll cost=T3.e[i].cost;
        if (v==F)
            continue;
        s3.cdp[v]=s3.cdp[u]+cost;
        s3.dep[v]=s3.dep[u]+1;
        dfs3(v,u);
        s3.st[++s3.ct][0]=u;
    }
}
il void dfs4(int u,int F,int s)
{
    sz[u]=1;
    for (rint i=fr[u];i;i=e[i].nxt)
    {
        int v=e[i].v;
        if (v==F || vis[i >> 1])
            continue;
        dfs4(v,u,s);
        sz[u]+=sz[v];
        if (cmx(sz[v],s-sz[v])<rtsz)
            rtsz=cmx(sz[v],s-sz[v]),rt=i;
    }
}
il void dfs5(int u,int F,int opt)
{
    if (u<=n)
        col[u]=opt;
    for (rint i=fr[u];i;i=e[i].nxt)
    {
        int v=e[i].v;
        ll cost=e[i].cost;
        if (v==F || vis[i >> 1])
            continue;
        kdp[v]=kdp[u]+cost;
        dfs5(v,u,opt);
    }
}
namespace BT
{
    int gn,tot=1,q[N],fr[M];
    int sz[M];
    ll val[M],kdp[M];
    node e[M << 1];
    bool vis[M];
};
namespace VT3
{
    int tot,fr[N];
    node e[N << 1];
    int t,st[N];
    ll dp[2][2][N];
    il void add(int x,int y)
    {
        ++tot;
        e[tot]=node(fr[x],y),fr[x]=tot;
    }
    il void ins(int x)
    {
        if (!t)
        {
            st[++t]=x;
            return;
        }
        int g=s3.lca(x,st[t]);
        while (t>1 && s3.dep[g]<s3.dep[st[t-1]])
            add(st[t-1],st[t]),--t;
        if (s3.dep[g]<s3.dep[st[t]])
            add(g,st[t]),t--;
        if (!t || st[t]!=g)
            st[++t]=g;
        st[++t]=x;
    }
    il void dfs8(int u)
    {
        dp[0][0][u]=dp[0][1][u]=dp[1][0][u]=dp[1][1][u]=-LINF;
        if (u<=n && col[u]>=0 && col2[u]>=0)
            dp[col[u]][col2[u]][u]=BT::val[u];
        for (rint i=fr[u];i;i=e[i].nxt)
        {
            int v=e[i].v;
            dfs8(v);
            ans=cmx(ans,dp[0][0][u]+dp[1][1][v]-(s3.cdp[u] << 1LL));
            ans=cmx(ans,dp[0][1][u]+dp[1][0][v]-(s3.cdp[u] << 1LL));
            ans=cmx(ans,dp[0][0][v]+dp[1][1][u]-(s3.cdp[u] << 1LL));
            ans=cmx(ans,dp[0][1][v]+dp[1][0][u]-(s3.cdp[u] << 1LL));
            dp[0][0][u]=cmx(dp[0][0][u],dp[0][0][v]);
            dp[0][1][u]=cmx(dp[0][1][u],dp[0][1][v]);
            dp[1][0][u]=cmx(dp[1][0][u],dp[1][0][v]);
            dp[1][1][u]=cmx(dp[1][1][u],dp[1][1][v]);
        }
    }
    il void Clear(int u)
    {
        col2[u]=-1;
        for (rint i=fr[u];i;i=e[i].nxt)
            Clear(e[i].v);
        fr[u]=0;
    }
};
namespace VT2
{
    int ct=0,dfn[N];
};
namespace BT
{
    int rtsz,rt;
    il void add(int x,int y,ll z)
    {
        ++tot;
        e[tot]=node(fr[x],y,z),fr[x]=tot;
    }
    il void add_edge(int x,int y,ll z)
    {
        add(x,y,z),add(y,x,z);
    }
    il void dfs4(int u,int F,int s)
    {
        sz[u]=1;
        for (rint i=fr[u];i;i=e[i].nxt)
        {
            int v=e[i].v;
            ll cost=e[i].cost;
            if (v==F || vis[i >> 1])
                continue;
            dfs4(v,u,s);
            sz[u]+=sz[v];
            if (cmx(sz[v],s-sz[v])<rtsz)
                rtsz=cmx(sz[v],s-sz[v]),rt=i;
        }
    }
    il void dfs5(int u,int F,int opt)
    {
        if (col[u]>=0 && u<=n)
            col2[u]=opt,val[u]=::kdp[u]+kdp[u]+s3.cdp[u];
        for (rint i=fr[u];i;i=e[i].nxt)
        {
            int v=e[i].v;
            ll cost=e[i].cost;
            if (v==F || vis[i >> 1])
                continue;
            kdp[v]=kdp[u]+cost;
            dfs5(v,u,opt);
        }
    }
    il void Clear(int u,int F)
    {
        for (rint i=fr[u];i;i=e[i].nxt)
        {
            int v=e[i].v;
            if (v==F)
                continue;
            Clear(v,u);
        }
        fr[u]=0;
    }
};
namespace VT
{
    int tot,fr[N];
    node e[N << 1];
    int t,st[N],c[2][N];
    il void add(int x,int y,ll z)
    {
        ++tot;
        e[tot]=node(fr[x],y,z),fr[x]=tot;
    }
    il void ins(int x)
    {
        if (!t)
        {
            st[++t]=x;
            return;
        }
        int g=s2.lca(x,st[t]);
        while (t>1 && s2.dep[g]<s2.dep[st[t-1]])
            add(st[t-1],st[t],s2.dis(st[t-1],st[t])),--t;
        if (s2.dep[g]<s2.dep[st[t]])
            add(g,st[t],s2.dis(g,st[t])),t--;
        if (!t || st[t]!=g)
            st[++t]=g;
        st[++t]=x;
    }
    il void dfs6(int u,int F)
    {
        int tt=0,lst;
        rint i=fr[u];
        if (e[i].v==F)
        	i=e[i].nxt;
        while (i) 
        {
            int v=e[i].v;
            ll cost=e[i].cost;
            i=e[i].nxt;
            if (e[i].v==F)
            	i=e[i].nxt;
            ++tt;
            if (tt==1)
                BT::add_edge(u,v,cost),lst=u; else
            if (i)
                ++BT::gn,BT::add_edge(lst,BT::gn,0),BT::add_edge(BT::gn,v,cost),lst=BT::gn; else
                BT::add_edge(lst,v,cost);
            dfs6(v,u);
        }
    }
    il void solve(int u,int s,int l,int r)
    {
        if (l>=r)
            return;
        BT::rtsz=INF;
        BT::dfs4(u,0,s);
        if (BT::rtsz==INF)
            return;
        BT::vis[BT::rt >> 1]=true;
        BT::kdp[BT::e[BT::rt].v]=0,BT::kdp[BT::e[BT::rt^1].v]=BT::e[BT::rt].cost;
        BT::dfs5(BT::e[BT::rt].v,0,0),BT::dfs5(BT::e[BT::rt^1].v,0,1);
        VT3::t=0;
        for (rint i=l;i<=r;++i)
            VT3::ins(VT2::dfn[i]);
        for (rint i=2;i<=VT3::t;++i)
            VT3::add(VT3::st[i-1],VT3::st[i]);
        VT3::dfs8(VT3::st[1]);
        c[0][0]=c[1][0]=0;
        for (rint i=l;i<=r;++i)
            c[col2[VT2::dfn[i]]][++c[col2[VT2::dfn[i]]][0]]=VT2::dfn[i];
        VT3::Clear(VT3::st[1]);
        VT3::tot=0;
        int L=l-1;
        for (rint j=1;j<=c[0][0];++j)
            VT2::dfn[++L]=c[0][j];
        for (rint j=1;j<=c[1][0];++j)
            VT2::dfn[++L]=c[1][j];
        int k=BT::rt,ts=s-BT::sz[BT::e[k].v],mid=l+c[0][0]-1;
        solve(BT::e[k].v,BT::sz[BT::e[k].v],l,mid),solve(BT::e[k^1].v,ts,mid+1,r);
        BT::vis[k >> 1]=false;
    }
    il void calc(int s)
    {
        int u=st[1];
        BT::gn=n;
        dfs6(u,0);
        solve(st[1],BT::gn-n+s,1,s);
        BT::Clear(u,0),BT::tot=1;
    }
    il void Clear(int u)
    {
        col[u]=-1;
        for (rint i=fr[u];i;i=e[i].nxt)
            Clear(e[i].v);
        fr[u]=0;
    }
};
il void solve(int u,int s,int l,int r)
{
	if (l>=r)
		return;
    rtsz=INF;
    dfs4(u,0,s);
    if (rtsz==INF)
        return;
    vis[rt >> 1]=true;
    kdp[e[rt].v]=0,kdp[e[rt^1].v]=e[rt].cost;
    dfs5(e[rt].v,0,0),dfs5(e[rt^1].v,0,1);
    VT::t=0;
    for (rint i=l;i<=r;++i)
        VT::ins(s2.dfn[i]);
    for (rint i=2;i<=VT::t;++i)
        VT::add(VT::st[i-1],VT::st[i],s2.dis(VT::st[i-1],VT::st[i]));
    memcpy(VT2::dfn+1,s3.dfn+l,(r-l+1)*sizeof(int));
    VT::calc(r-l+1);
    c[0][0]=c[1][0]=0;
    for (rint i=l;i<=r;++i)
        c[col[s2.dfn[i]]][++c[col[s2.dfn[i]]][0]]=s2.dfn[i];
    int L=l-1;
    for (rint j=1;j<=c[0][0];++j)
        s2.dfn[++L]=c[0][j];
    for (rint j=1;j<=c[1][0];++j)
        s2.dfn[++L]=c[1][j];
    c[0][0]=c[1][0]=0;
    for (rint i=l;i<=r;++i)
        c[col[s3.dfn[i]]][++c[col[s3.dfn[i]]][0]]=s3.dfn[i];
    L=l-1;
    for (rint j=1;j<=c[0][0];++j)
        s3.dfn[++L]=c[0][j];
    for (rint j=1;j<=c[1][0];++j)
        s3.dfn[++L]=c[1][j];
    VT::Clear(VT::st[1]),VT::tot=0;
    int k=rt,ts=s-sz[e[k].v],mid=l+c[0][0]-1;
    solve(e[k].v,sz[e[k].v],l,mid),solve(e[k^1].v,ts,mid+1,r);
}
int main()
{
    n=iread(),gn=n;
    for (rint i=1;i<n;++i)
    {
        x=iread(),y=iread(),z=lread();
        T1.add(x,y,z),T1.add(y,x,z);
    }
    dfs1(1,0);
    for (rint i=1;i<n;++i)
    {
        x=iread(),y=iread(),z=lread();
        T2.add(x,y,z),T2.add(y,x,z);
    }
    s2.dep[1]=1,s2.cdp[1]=0,dfs2(1,0);
    lg2[0]=-1;
    for (rint i=1;i<=s2.ct;++i)
        lg2[i]=lg2[i >> 1]+1;
    for (rint j=1;j<=lg2[s2.ct];++j)
        for (rint i=1;i<=s2.ct-(1 << j)+1;++i)
            s2.st[i][j]=(s2.dep[s2.st[i][j-1]]<s2.dep[s2.st[i+(1 << j-1)][j-1]])?s2.st[i][j-1]:s2.st[i+(1 << j-1)][j-1];
    for (rint i=1;i<n;++i)
    {
        x=iread(),y=iread(),z=lread();
        T3.add(x,y,z),T3.add(y,x,z);
    }
    s3.dep[1]=1,s3.cdp[1]=0,dfs3(1,0);
    for (rint j=1;j<=lg2[s3.ct];++j)
        for (rint i=1;i<=s3.ct-(1 << j)+1;++i)
            s3.st[i][j]=(s3.dep[s3.st[i][j-1]]<s3.dep[s3.st[i+(1 << j-1)][j-1]])?s3.st[i][j-1]:s3.st[i+(1 << j-1)][j-1];
    for (rint i=1;i<=n;++i)
        col[i]=col2[i]=-1;
    solve(1,gn,1,n);
    printf("%lld\n",ans);
    return 0;
}

设第一棵树的边分树中,分治得的两棵子树,其中的节点\(u\)的深度为\(dep'(u)\)

可以考虑树上最长路径的性质,如果有两个点集在树上的直径分别为\((u_1,v_1)\)\((u_2,v_2)\),那么把这两个点集合并后,新点集的直径必然为\((u_1,v_1),(u_1,v_2),(u_2,v_1),(u_2,v_2)\)其中之一。

那么我们同样在第二棵树的\(lca\)处统计答案,维护子树黑色点集和白色点集,互相合并,同时让直径带上权,为\(dep'(u)+dep2(u)\),用同色点集合并直径,用异色点集统计答案。

\(Code:\)

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 100005
#define M 200005
#define ll long long
#define rint register int
#define il inline
using namespace std;
const int INF=1000000007;
const ll LINF=491919191919191919;
int n,x,y,gn;
ll z;
struct node
{
    int nxt,v;
    ll cost;
    il node (int Nxt=0,int D1=0,ll D2=0)
    {
        nxt=Nxt,v=D1,cost=D2;
    }
};
struct edge
{
    int tot=0,fr[N];
    node e[N << 1];
    il void add(int x,int y,ll z)
    {
        ++tot;
        e[tot]=node(fr[x],y,z),fr[x]=tot;
    }
}T1,T2,T3;
int lg2[N << 1];
struct ST
{
    int cnt,ct,dep[N],dfn[N],bg[N],st[N << 1][22];
    ll cdp[N];
    il int lca(int x,int y)
    {
        x=bg[x],y=bg[y];
        if (x>y)
            swap(x,y);
        int k=lg2[y-x+1];
        return (dep[st[x][k]]<dep[st[y-(1 << k)+1][k]])?st[x][k]:st[y-(1 << k)+1][k];
    }
    il ll dis(int x,int y)
    {
        return cdp[x]+cdp[y]-(cdp[lca(x,y)] << 1LL);
    }
}s2,s3;
int tot=1,fr[M];
node e[M << 1];
int rt,rtsz,s[N];
int sz[M],col[N];
int c[2][N];
ll ans=-LINF,mx,kdp[M],val[N];
bool vis[M];
char buf[1 << 23],*p1=buf,*p2=buf,obuf[1 << 23],*O=obuf;
#define getchar() (p1==p2 && (p2=(p1=buf)+fread(buf,1,1 << 21,stdin),p1==p2)?EOF:*p1++)
il int iread()
{
	int s=0;
	char c=getchar();
	while (c<'0' || c>'9')
		c=getchar();
	while ('0'<=c && c<='9')
		s=(s << 1)+(s << 3)+(c^48),c=getchar();
	return s;
}
il ll lread()
{
	ll s=0;
	char c=getchar();
	while (c<'0' || c>'9')
		c=getchar();
	while ('0'<=c && c<='9')
		s=(s << 1)+(s << 3)+(c^48),c=getchar();
	return s;
}
template<typename T>
il T cmx(T x,T y)
{
    return (x>y)?x:y;
}
il void add(int x,int y,ll z)
{
    ++tot;
    e[tot]=node(fr[x],y,z),fr[x]=tot;
}
il void add_edge(int x,int y,ll z)
{
    add(x,y,z),add(y,x,z);
}
il void dfs1(int u,int F)
{
    int tt=0,lst;
    rint i=T1.fr[u];
    if (T1.e[i].v==F)
    	i=T1.e[i].nxt;
    while (i)
    {
        int v=T1.e[i].v;
        ll cost=T1.e[i].cost;
        i=T1.e[i].nxt;
        if (T1.e[i].v==F)
        	i=T1.e[i].nxt;
        ++tt;
        if (tt==1)
            add_edge(u,v,cost),lst=u; else
        if (i)
            ++gn,add_edge(lst,gn,0),add_edge(gn,v,cost),lst=gn; else
            add_edge(lst,v,cost);
        dfs1(v,u);
    }
}
il void dfs2(int u,int F)
{
    s2.dfn[++s2.cnt]=u,s2.st[++s2.ct][0]=u,s2.bg[u]=s2.ct;
    for (rint i=T2.fr[u];i;i=T2.e[i].nxt)
    {
        int v=T2.e[i].v;
        ll cost=T2.e[i].cost;
        if (v==F)
            continue;
        s2.cdp[v]=s2.cdp[u]+cost;
        s2.dep[v]=s2.dep[u]+1;
        dfs2(v,u);
        s2.st[++s2.ct][0]=u;
    }
}
il void dfs3(int u,int F)
{
    s3.dfn[++s3.cnt]=u,s[u]=s3.cnt,s3.st[++s3.ct][0]=u,s3.bg[u]=s3.ct;
    for (rint i=T3.fr[u];i;i=T3.e[i].nxt)
    {
        int v=T3.e[i].v;
        ll cost=T3.e[i].cost;
        if (v==F)
            continue;
        s3.cdp[v]=s3.cdp[u]+cost;
        s3.dep[v]=s3.dep[u]+1;
        dfs3(v,u);
        s3.st[++s3.ct][0]=u;
    }
}
il void dfs4(int u,int F,int s)
{
    sz[u]=1;
    for (rint i=fr[u];i;i=e[i].nxt)
    {
        int v=e[i].v;
        if (v==F || vis[i >> 1])
            continue;
        dfs4(v,u,s);
        sz[u]+=sz[v];
        if (cmx(sz[v],s-sz[v])<rtsz)
            rtsz=cmx(sz[v],s-sz[v]),rt=i;
    }
}
il void dfs5(int u,int F,int opt)
{
    if (u<=n)
        col[u]=opt,val[u]=kdp[u]+s2.cdp[u];
    for (rint i=fr[u];i;i=e[i].nxt)
    {
        int v=e[i].v;
        ll cost=e[i].cost;
        if (v==F || vis[i >> 1])
            continue;
        kdp[v]=kdp[u]+cost;
        dfs5(v,u,opt);
    }
}
il void ckmx(ll &x,ll y)
{
    x=(x>y)?x:y;
}
struct DpNode
{
    ll s;
    int x,y;
    DpNode (ll S=0,int X=0,int Y=0)
    {
        s=S,x=X,y=Y;
    }
};
namespace VT
{
    int tot,fr[N];
    node e[N << 1];
    int t,st[N];
    DpNode dp[N][2];
    DpNode DINF=DpNode(-INF,-1,-1);
    il void add(int x,int y)
    {
        ++tot;
        e[tot]=node(fr[x],y),fr[x]=tot;
    }
    il void ins(int x)
    {
        if (!t)
        {
            st[++t]=x;
            return;
        }
        int g=s2.lca(x,st[t]);
        while (t>1 && s2.dep[g]<s2.dep[st[t-1]])
            add(st[t-1],st[t]),--t;
        if (s2.dep[g]<s2.dep[st[t]])
            add(g,st[t]),t--;
        if (!t || st[t]!=g)
            st[++t]=g;
        st[++t]=x;
    }
    il void dfs6(int u)
    {
        dp[u][0]=dp[u][1]=DINF;
        if (u<=n && col[u]!=-1)
            dp[u][col[u]]=DpNode(val[u],u,u);
        for (int i=fr[u];i;i=e[i].nxt)
        {
            int v=e[i].v;
            dfs6(v);
            ckmx(ans,s3.dis(dp[u][0].x,dp[v][1].x)+val[dp[u][0].x]+val[dp[v][1].x]-(s2.cdp[u] << 1LL));
            ckmx(ans,s3.dis(dp[u][0].x,dp[v][1].y)+val[dp[u][0].x]+val[dp[v][1].y]-(s2.cdp[u] << 1LL));
            ckmx(ans,s3.dis(dp[u][0].y,dp[v][1].x)+val[dp[u][0].y]+val[dp[v][1].x]-(s2.cdp[u] << 1LL));
            ckmx(ans,s3.dis(dp[u][0].y,dp[v][1].y)+val[dp[u][0].y]+val[dp[v][1].y]-(s2.cdp[u] << 1LL));
            ckmx(ans,s3.dis(dp[u][1].x,dp[v][0].x)+val[dp[u][1].x]+val[dp[v][0].x]-(s2.cdp[u] << 1LL));
            ckmx(ans,s3.dis(dp[u][1].x,dp[v][0].y)+val[dp[u][1].x]+val[dp[v][0].y]-(s2.cdp[u] << 1LL));
            ckmx(ans,s3.dis(dp[u][1].y,dp[v][0].x)+val[dp[u][1].y]+val[dp[v][0].x]-(s2.cdp[u] << 1LL));
            ckmx(ans,s3.dis(dp[u][1].y,dp[v][0].y)+val[dp[u][1].y]+val[dp[v][0].y]-(s2.cdp[u] << 1LL));
            if (s3.dis(dp[u][0].x,dp[v][0].x)+val[dp[u][0].x]+val[dp[v][0].x]>dp[u][0].s)
                dp[u][0]=DpNode(s3.dis(dp[u][0].x,dp[v][0].x)+val[dp[u][0].x]+val[dp[v][0].x],dp[u][0].x,dp[v][0].x);
            if (s3.dis(dp[u][0].x,dp[v][0].y)+val[dp[u][0].x]+val[dp[v][0].y]>dp[u][0].s)
                dp[u][0]=DpNode(s3.dis(dp[u][0].x,dp[v][0].y)+val[dp[u][0].x]+val[dp[v][0].y],dp[u][0].x,dp[v][0].y);
            if (s3.dis(dp[u][0].y,dp[v][0].x)+val[dp[u][0].y]+val[dp[v][0].x]>dp[u][0].s)
                dp[u][0]=DpNode(s3.dis(dp[u][0].y,dp[v][0].x)+val[dp[u][0].y]+val[dp[v][0].x],dp[u][0].y,dp[v][0].x);
            if (s3.dis(dp[u][0].y,dp[v][0].y)+val[dp[u][0].y]+val[dp[v][0].y]>dp[u][0].s)
                dp[u][0]=DpNode(s3.dis(dp[u][0].y,dp[v][0].y)+val[dp[u][0].y]+val[dp[v][0].y],dp[u][0].y,dp[v][0].y);
            if (s3.dis(dp[u][1].x,dp[v][1].x)+val[dp[u][1].x]+val[dp[v][1].x]>dp[u][1].s)
                dp[u][1]=DpNode(s3.dis(dp[u][1].x,dp[v][1].x)+val[dp[u][1].x]+val[dp[v][1].x],dp[u][1].x,dp[v][1].x);
            if (s3.dis(dp[u][1].x,dp[v][1].y)+val[dp[u][1].x]+val[dp[v][1].y]>dp[u][1].s)
                dp[u][1]=DpNode(s3.dis(dp[u][1].x,dp[v][1].y)+val[dp[u][1].x]+val[dp[v][1].y],dp[u][1].x,dp[v][1].y);
            if (s3.dis(dp[u][1].y,dp[v][1].x)+val[dp[u][1].y]+val[dp[v][1].x]>dp[u][1].s)
                dp[u][1]=DpNode(s3.dis(dp[u][1].y,dp[v][1].x)+val[dp[u][1].y]+val[dp[v][1].x],dp[u][1].y,dp[v][1].x);
            if (s3.dis(dp[u][1].y,dp[v][1].y)+val[dp[u][1].y]+val[dp[v][1].y]>dp[u][1].s)
                dp[u][1]=DpNode(s3.dis(dp[u][1].y,dp[v][1].y)+val[dp[u][1].y]+val[dp[v][1].y],dp[u][1].y,dp[v][1].y);
        }
    }
    il void Clear(int u)
    {
        col[u]=-1,val[u]=-LINF;
        for (rint i=fr[u];i;i=e[i].nxt)
            Clear(e[i].v);
        fr[u]=0;
    }
};
il void solve(int u,int s,int l,int r)
{
	if (l>=r)
		return;
    rtsz=INF;
    dfs4(u,0,s);
    if (rtsz==INF)
        return;
    vis[rt >> 1]=true;
    kdp[e[rt].v]=0,kdp[e[rt^1].v]=e[rt].cost;
    dfs5(e[rt].v,0,0),dfs5(e[rt^1].v,0,1);
    VT::t=0;
    for (rint i=l;i<=r;++i)
        VT::ins(s2.dfn[i]);
    for (rint i=2;i<=VT::t;++i)
        VT::add(VT::st[i-1],VT::st[i]);
    VT::dfs6(VT::st[1]);
    c[0][0]=c[1][0]=0;
    for (rint i=l;i<=r;++i)
        c[col[s2.dfn[i]]][++c[col[s2.dfn[i]]][0]]=s2.dfn[i];
    int L=l-1;
    for (rint j=1;j<=c[0][0];++j)
        s2.dfn[++L]=c[0][j];
    for (rint j=1;j<=c[1][0];++j)
        s2.dfn[++L]=c[1][j];
    VT::Clear(VT::st[1]),VT::tot=0;
    int k=rt,ts=s-sz[e[k].v],mid=l+c[0][0]-1;
    solve(e[k].v,sz[e[k].v],l,mid),solve(e[k^1].v,ts,mid+1,r);
}
int main()
{
    n=iread(),gn=n;
    for (rint i=1;i<n;++i)
    {
        x=iread(),y=iread(),z=lread();
        T1.add(x,y,z),T1.add(y,x,z);
    }
    dfs1(1,0);
    for (rint i=1;i<n;++i)
    {
        x=iread(),y=iread(),z=lread();
        T2.add(x,y,z),T2.add(y,x,z);
    }
    s2.dep[1]=1,s2.cdp[1]=0,dfs2(1,0);
    lg2[0]=-1;
    for (rint i=1;i<=s2.ct;++i)
        lg2[i]=lg2[i >> 1]+1;
    for (rint j=1;j<=lg2[s2.ct];++j)
        for (rint i=1;i<=s2.ct-(1 << j)+1;++i)
            s2.st[i][j]=(s2.dep[s2.st[i][j-1]]<s2.dep[s2.st[i+(1 << j-1)][j-1]])?s2.st[i][j-1]:s2.st[i+(1 << j-1)][j-1];
    for (rint i=1;i<n;++i)
    {
        x=iread(),y=iread(),z=lread();
        T3.add(x,y,z),T3.add(y,x,z);
    }
    s3.dep[1]=1,s3.cdp[1]=0,dfs3(1,0);
    for (rint j=1;j<=lg2[s3.ct];++j)
        for (rint i=1;i<=s3.ct-(1 << j)+1;++i)
            s3.st[i][j]=(s3.dep[s3.st[i][j-1]]<s3.dep[s3.st[i+(1 << j-1)][j-1]])?s3.st[i][j-1]:s3.st[i+(1 << j-1)][j-1];
    for (rint i=1;i<=n;++i)
        col[i]=-1;
    solve(1,gn,1,n);
    printf("%lld\n",ans);
    return 0;
}
posted @ 2020-10-25 21:24  GK0328  阅读(49)  评论(0编辑  收藏  举报