In fact, before long I was thinking about the same general understanding
However, due to too konjac
hard to accomplish
In January, before about my brush tree dp, and brush to this question
Ah, I get to 0pts good results with dp
Anyway, I now understand that
#include<bits/stdc++.h> #define re return #define ll long long #define dec(i,l,r) for(register int i=l;i>=r;--i) #define inc(i,l,r) for(register int i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } const int maxn=300005; int cnt,k,n,m,hd[maxn],fa[maxn][21]; int size1,pos[maxn],vis[maxn]; long long dis[maxn][21]; struct node{ int to,nt,val; }e[maxn<<1]; inline void add(int x,int y,int z) { e[++k].to=y;e[k].nt=hd[x];hd[x]=k;e[k].val=z; e[++k].to=x;e[k].nt=hd[y];hd[y]=k;e[k].val=z; } inline void dfs(int x) { for(int i=0;fa[fa[x][i]][i];++i) { fa[x][i+1]=fa[fa[x][i]][i]; dis[x][i+1]=dis[x][i]+dis[fa[x][i]][i]; } for(int i=hd[x];i;i=e[i].nt) { int v=e[i].to; if(v==fa[x][0])continue; fa[v][0]=x; dis[v][0]=e[i].val; dfs(v); } } struct lll { int fr,left_dis,id; bool operator<(lll c)const { re left_dis<c.left_dis; } }a[maxn]; int cnta,cntb,need[maxn]; struct lli { int val,id; bool operator<(lli c)const { re val<c.val; } }b[maxn]; inline bool dfs1(int x) { if(vis[x])re 1; int siz=0; for(int i=hd[x];i;i=e[i].nt) { int v=e[i].to; if(v==fa[x][0])continue; siz|=1; if(dfs1(v)==0) {vis[x]=0;re 0;} } if(!siz) {vis[x]=0;re 0;} vis[x]=1; re 1; } inline bool check(ll x) { cntb=cnta=0; inc(i,0,n)vis[i]=0; inc(i,1,m) { int v=pos[i],now=0; On Dec (I, 20 is , 0 ) IF (FA [V] [I]> . 1 && DIS [V] [I] + now <= X) {now + = DIS [V] [I]; V = FA [V] [ I];} int left = now-DIS-X [V] [ 0 ]; IF (FA [V] [ 0 ] == . 1 && left> = 0 ) // at the boundary point // can return point has been injection or tie // left is a departure from the maximum distance that can be traveled a [++ CNTA] = (LLL) {V, left, CNTA}; the else VIS [V] = 1 ; } // will not be blocked dot mark for ( int I = HD [ . 1 ]; I; I = E [I] .nt) { int= V E [I] .to; DFS1 (V); } Sort (A + . 1 , A + + CNTA . 1 ); int Nowa = 0 ; // find the smallest can not return to the starting node (unblocked) value inc (i , . 1 , CNTA) { IF (VIS [A [I] .fr] && A [I] .left_dis <DIS [A [I] .fr] [! 0 ]) { A [I] .left_dis = - . 1 ; VIS [A [I] .fr] = . 1 ; - Nowa; } } Sort (A + . 1 , A + + CNTA . 1); for(int i=hd[1];i;i=e[i].nt) { int v=e[i].to; if(!vis[v])b[++cntb]=(lli){e[i].val,v}; } sort(b+1,b+cntb+1); int nowb=1; inc(i,nowa+1,cnta) { if(b[nowb].val<=a[i].left_dis)++nowb; if(nowb==cntb+1)re 1; } re 0; } int main() { freopen("in.txt","r",stdin); // freopen("testdata.in","r",stdin); int x,y,z; ll l=0,r=0; rd(n); inc(i,2,n) { rd(x),rd(y),rd(z); add(x,y,z); r+=z; } //dfs得到倍增数组 for(int i=hd[1];i;i=e[i].nt) { ++size1; int v=e[i].to; fa[v][0]=1;dis[v][0]=e[i].val; dfs(v); } rd(m); if(m<size1){printf("-1");re 0;} inc(i,1,m)rd(pos[i]); while(l<=r) { int mid=(l+r)>>1; if(check(mid))r=mid-1; else l=mid+1; } printf("%lld",l); re 0; }