按时返回束带结发是弗兰克萨来看交管理费发的链接鬼地方个;就共IER级额是个节日人

Ishar-zdl的博客 / 2024-10-08 / 原文

#include<bits/stdc++.h>
#define int long long
#define fo(i,s,t) for(int i=s;i<=t;++i)
typedef long long ll;
typedef unsigned long long ull;
inline int read(){char ch=getchar();int x=0,f=1;for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;for(;ch>='0'&&ch<='9';ch=getchar())x=(x<<3)+(x<<1)+(ch^48);return x*f;}
const int N=1.5e5;
int n;
struct EDGE{int v,w;};
std::vector<EDGE> e[N];
struct NODE{
    int a,b;
    friend bool operator<(const NODE &a,const NODE &b){
        return a.a==b.a?a.b<b.b:a.a<b.a;
    }
}zc[N];
std::set<NODE> s[N];
inline bool dfs(int x,int fa,int mid){
    s[x].clear();
    int ls=0,rs=0,vl,vr;
    for(auto it:e[x]){
        int v=it.v,w=it.w;if(v==fa)continue;
        if(!dfs(v,x,mid))return 0;
        if(ls)rs=v,vr=w;
        else ls=v,vl=w;
    }
    if(!ls&&!rs){s[x].insert({0,0});return 1;}
    int cnt=0;
    auto it=s[rs].begin(),en=--s[rs].end();
    for(auto now:s[ls]){
        while(it!=en&&(*next(it)).a+now.b+vl+vr<=mid)++it;
        if((*it).a+now.b+vl+vr<=mid)zc[++cnt]={now.a+vl,(*it).b+vr};
    }
    it=s[ls].begin(),en=--s[ls].end();
    for(auto now:s[rs]){
        while(it!=en&&(*next(it)).a+now.b+vl+vr<=mid)++it;
        if((*it).a+now.b+vl+vr<=mid)zc[++cnt]={now.a+vr,(*it).b+vl};
    }
    if(!cnt)return 0;
    std::sort(zc+1,zc+cnt+1);
    s[x].insert(zc[1]);
    int las=1;
    for(int i=2;i<=cnt;++i)
        if(zc[i].b<zc[las].b&&zc[i].a>zc[las].a)s[x].insert(zc[i]),las=i;
    if(s[x].empty())return false;
    return true;
}
signed main(){
    freopen("trip.in","r",stdin);freopen("trip.out","w",stdout);
    std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0);
    n=read();
    int l=0,r=0,res=0;
    for(int i=2;i<=n;++i){
        int u=read(),w=read();e[u].push_back({i,w});e[i].push_back({u,w});
        r+=w;
    }
    while(l<=r){
        int mid=l+r>>1;
        if(dfs(1,0,mid))r=mid-1,res=mid;
        else l=mid+1;
    }
    std::cout<<res<<'\n';
}