并不对劲的bzoj5152:loj2339:uoj347:p4220:[WC2018]通道

#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define rep(i,x,y) for(int i=(x);i<=(y);++i)
#define dwn(i,x,y) for(int i=(x);i>=(y);--i)
#define view(u,k) for(int k=fir[u];~k;k=nxt[k])
#define view2(u,k) for(int k=fs[u];~k;k=nt[k])
#define maxn 100001
#define maxm (maxn<<1)
#define pb push_back
#define LL long long
#define pil pair<int ,LL >
#define pii pair<int ,int >
#define mp make_pair
#define fi first
#define se second
#define so to[id][u][i].fi
#define wso to[id][u][i].se
using namespace std;
LL read()
{
    LL x=0,f=1;char ch=getchar();
    while(!isdigit(ch)&&ch!='-')ch=getchar();
    if(ch=='-')f=-1,ch=getchar();
    while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    return x*f;
}
void write(LL x)
{
    if(x==0){putchar('0'),putchar('\n');return;}
    int f=0;char ch[20];
    if(x<0)putchar('-'),x=-x;
    while(x)ch[++f]=x%10+'0',x/=10;
    while(f)putchar(ch[f--]);
    putchar('\n');
    return;
}
vector<pil >to[3][maxn];
pii a[2][maxn];
LL w[maxm<<1],dep[3][maxn],st[20][maxm],d[maxn],ans;
int n,fir[maxm],nxt[maxm<<1],v[maxm<<1],tot,cnt,dfn[maxn],tim,dfn2[maxn],lg[maxm];
int sumsiz,minsiz,wt,fs[maxn],nt[maxm],vv[maxm],cnte,stk[maxn],tp,rt,id,color;
int top[maxn],siz[maxm],son[maxn],ancs[maxn],vis[maxm<<1],col[maxn],p[maxn],cntp/*,tpu,tpv*/;
void ade(int u1,int v1,LL w1){v[cnt]=v1,w[cnt]=w1,nxt[cnt]=fir[u1],fir[u1]=cnt++;}//0
void ade2(int u1,int v1){vv[cnte]=v1,nt[cnte]=fs[u1],fs[u1]=cnte++;}//1
void getst(int u,int fa)
{
    dfn2[u]=++tim,st[0][tim]=dep[id][u];int lim=to[id][u].size();
    rep(i,0,lim-1)if(so!=fa)dep[id][so]=dep[id][u]+wso,getst(so,u),st[0][++tim]=dep[id][u];
}//2
inline LL deplca(int x,int y)
{
    x=dfn2[x],y=dfn2[y];
    if(x>y)swap(x,y);
    int len=y-x+1;
    return min(st[lg[len]][x],st[lg[len]][y-(1<<lg[len])+1]);
}//2
#define dis(x,y) (dep[2][x]+dep[2][y]-2ll*deplca(x,y))
#define Dis(x,y) ((!x||!y)?0:(w[wt]+d[x]+d[y]+dep[1][x]+dep[1][y]+dis(x,y)))
void get2(int u,int fa)
{
    int now=u,ff=0,lim=to[id][u].size();
    rep(i,0,lim-1)if(so!=fa)
    {
        if(ff)tot++,ade(tot,now,0),ade(now,tot,0),now=tot;
        ade(now,so,wso),ade(so,now,wso),ff=1;
    } 
    rep(i,0,lim-1)if(so!=fa)get2(so,u);
}//0
void getson(int u)
{
    siz[u]=1;dfn[u]=++tim;int lim=to[id][u].size();
    rep(i,0,lim-1)if(so!=ancs[u])
    {
        dep[id][so]=dep[id][u]+wso,ancs[so]=u,dep[0][so]=dep[0][u]+1,getson(so),siz[u]+=siz[so];
        if(!son[u]||siz[so]>siz[son[u]])son[u]=so;
    }
}//1
void gettop(int u,int anc)
{
    top[u]=anc;int lim=to[id][u].size();
    if(son[u])gettop(son[u],anc);
    rep(i,0,lim-1)if(so!=ancs[u]&&so!=son[u])gettop(so,so);
}//1
int Lca(int x,int y)
{
    while(top[x]!=top[y])
    {
        if(dep[0][top[x]]<dep[0][top[y]])swap(x,y);
        x=ancs[top[x]];
    }
    if(dep[0][x]<dep[0][y])swap(x,y);
    return y;
}//1
void getsiz(int u,int fa)
{
    siz[u]=1;
    view(u,k)if(!vis[k]&&v[k]!=fa)
    {
        getsiz(v[k],u),siz[u]+=siz[v[k]];
        //cout<<"now:"<<k<<" siz:"<<max(siz[v[k]],sumsiz-siz[v[k]])<<" "<<sumsiz<<" "<<siz[v[k]]<<" u:"<<u<<" v:"<<v[k]<<endl;
        if(max(siz[v[k]],sumsiz-siz[v[k]])<minsiz)minsiz=max(siz[v[k]],sumsiz-siz[u]),wt=k/*,tpu=u,tpv=v[k]*/;
    }
}//0
void getp(int u,int fa,LL dist)
{
    if(u<=n)p[++cntp]=u,d[u]=dist,col[u]=color;
    view(u,k)if(v[k]!=fa&&!vis[k])getp(v[k],u,dist+w[k]);
}//0
bool cmp(int x,int y){return dfn[x]<dfn[y];}
void merge(pii x,pii & y)//y+=x
{
    pii res=y;
    if(Dis(x.fi,x.se)>Dis(res.fi,res.se))res=mp(x.fi,x.se);
    if(Dis(x.fi,y.fi)>Dis(res.fi,res.se))res=mp(x.fi,y.fi);
    if(Dis(x.fi,y.se)>Dis(res.fi,res.se))res=mp(x.fi,y.se);
    if(Dis(x.se,y.fi)>Dis(res.fi,res.se))res=mp(x.se,y.fi);
    if(Dis(x.se,y.se)>Dis(res.fi,res.se))res=mp(x.se,y.se);
    y=res;
}//1
void getans(int u,int fa)
{
    if(col[u]!=-1)a[col[u]][u]=mp(u,u),a[col[u]^1][u]=mp(0,0);
    else a[0][u]=a[1][u]=mp(0,0);
    view2(u,k)if(vv[k]!=fa)
    {
        getans(vv[k],u);
        ans=max(ans,Dis(a[0][u].fi,a[1][vv[k]].fi)-2ll*dep[1][u]);
        ans=max(ans,Dis(a[0][u].fi,a[1][vv[k]].se)-2ll*dep[1][u]);
        ans=max(ans,Dis(a[0][u].se,a[1][vv[k]].fi)-2ll*dep[1][u]);
        ans=max(ans,Dis(a[0][u].se,a[1][vv[k]].se)-2ll*dep[1][u]);
        ans=max(ans,Dis(a[1][u].fi,a[0][vv[k]].fi)-2ll*dep[1][u]);
        ans=max(ans,Dis(a[1][u].fi,a[0][vv[k]].se)-2ll*dep[1][u]);
        ans=max(ans,Dis(a[1][u].se,a[0][vv[k]].fi)-2ll*dep[1][u]);
        ans=max(ans,Dis(a[1][u].se,a[0][vv[k]].se)-2ll*dep[1][u]);
        //cout<<"u:"<<u<<" wt:"<<wt<<" res:"<<res<<endl; 
        merge(a[0][vv[k]],a[0][u]),merge(a[1][vv[k]],a[1][u]);
    }
}//1
void getwt(int u,int nowsiz)
{
    if(nowsiz==1)return;
    sumsiz=nowsiz,minsiz=n+1,getsiz(u,0);
    //cout<<"u:"<<u<<" nowsiz:"<<nowsiz<<" wt:"<<wt<<" "<<tpu<<" "<<tpv<<" "<<siz[tpu]<<" "<<siz[tpv]<<endl;
    int pu=v[wt],pv=v[wt^1],su=(siz[pu]>siz[pv])?nowsiz-siz[pv]:siz[pu],sv=(siz[pv]>siz[pu])?nowsiz-siz[pu]:siz[pv];
    vis[wt]=vis[wt^1]=1,cntp=0;
    color=0,getp(pu,0,0),color=1,getp(pv,0,0);
    sort(p+1,p+cntp+1,cmp);cnte=0;
    stk[tp=1]=p[1],fs[stk[1]]=-1;
    rep(i,2,cntp)
    {
        int nowu=p[i],lca=Lca(nowu,stk[tp]);fs[nowu]=-1;
        while(tp>1&&dep[0][stk[tp-1]]>=dep[0][lca])ade2(stk[tp-1],stk[tp]),ade2(stk[tp],stk[tp-1]),tp--;
        if(lca!=stk[tp])fs[lca]=col[lca]=-1,ade2(stk[tp],lca),ade2(lca,stk[tp]),stk[tp]=lca;stk[++tp]=nowu;
    }
    while(tp>1)ade2(stk[tp-1],stk[tp]),ade2(stk[tp],stk[tp-1]),tp--;
    rt=stk[1];
    getans(rt,0);
    getwt(pu,su),getwt(pv,sv);
}//0
int main()
{
    //freopen(".in","r",stdin);
    //freopen(".out","w",stdout);
    memset(fir,-1,sizeof(fir));
    n=read();
    rep(k,0,2)rep(i,1,n-1){int x=read(),y=read();LL z=read();to[k][x].pb(mp(y,z)),to[k][y].pb(mp(x,z));}
    id=1,getson(1),gettop(1,1),tim=0,id=2,getst(1,0),lg[0]=-1;
    rep(i,1,tim)lg[i]=lg[i>>1]+1;
    rep(k,1,lg[tim])for(int i=1;i+(1<<k)-1<=tim;++i)
        st[k][i]=min(st[k-1][i],st[k-1][i+(1<<(k-1))]);
    tot=n,id=0,get2(1,0);
    getwt(1,tot);
    write(ans);
    return 0;
}
/*
5
1 2 2
1 3 0
1 4 1
4 5 7
1 2 0
2 3 1
2 4 1
2 5 3
1 5 2
2 3 8
3 4 5
4 5 1
*/

猜你喜欢

转载自www.cnblogs.com/xzyf/p/10589964.html