Meaning
Given a weighted tree (N<=1E5), maintain a dynamic set (that is, insertion point and deletion point), and find the minimum distance from which to reach all points and return.
Analysis:
All points are reached and returned, which is twice times the weight of these dots connected with the least edges. In this way only dynamic computation, the least edge of the and.
Here, with 1 as the root node, run the DFS sequence.
Consider inserting: Then if the insertion point is DFS-ordered, there is a point in the middle of the DFS sequence in the set, and a smaller maximum point is found, and the smallest point is larger, because the insertion point within the two-point line is the smallest distance from the point.
Otherwise, the insertion point is externally, looking for the maximum and minimum points of the DFS sequence.
Delete is the reverse operation of the insert.
#pragma COMMENT (linker, "/stack:1024000000,1024000000") #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <set> #include <map> #include & lt;string> #include <list> #include <cstdlib> #include <queue> #include <stack> #include < cmath> #include <bitset> #include <cassert> #define ALL (a) A.begin (), A.end () #define CLR (A, X) memset (A, X. , sizeof a) #define X #define Y second #define PB push_back #define LOWBIT (x) (x& (x)) #define Lson T;1 #define Rson m+1,r,rt<<1|1 #define REP1 (i,x,y) for (int i=x;i<=y;i++) #define REP (i,n) for (int i=0;i< (int)
n;i++) using namespace std;
Const double EPS = 1e-10;
typedef long Long LL;
typedef long Long LL;
typedef pair<int, int> PII;
const int OO =0x3f3f3f3f;
const int maxn=100000+100;
const int deg=30;
struct Edge {int V, NXT, cap;} edge[maxn<<1]; int N, Head[maXN], tot, fa[maxn][deg], DEG[MAXN], SZ[MAXN];
void Init () {CLR (head,-1);
tot=0;
} void Addedge (int u, int v, int c) {edge[tot].v=v;
Edge[tot].cap=c;
Edge[tot].nxt=head[u];
head[u]=tot++;
} void Dfs (int u) {for (int i=1; i<deg; i++) fa[u][i]=fa[fa[u][i-1]][i-1];
Sz[u]=1;
for (int i=head[u]; ~i i=edge[i].nxt) {int v=edge[i].v;
if (v==fa[u][0]) continue;
deg[v]=deg[u]+1;
Fa[v][0]=u;
DFS (v);
SZ[U]+=SZ[V];
int par (int u, int det) {for (int i=0; det; det>>=1, i++) if (det&1) u=fa[u][i];
return u;
int LCA (int u, int v) {if (Deg[u]>deg[v]) swap (U, v);
int Tu=u, tv=v;
Tv=par (V, Deg[v]-deg[u]);
if (TU==TV) return tu;
for (int i=deg-1; i>=0; i--) {if (fa[tu][i]==fa[tv][i)) continue;
Tu=fa[tu][i], tv=fa[tv][i];
return fa[tu][0];
int ID[MAXN], cnt_=0;
ll D[MAXN]; void Init_dfs (int u,int F, lL len) {id[u] = ++cnt_;
D[u] = len;
for (int i=head[u]; ~i i=edge[i].nxt) {int v=edge[i].v;
if (v==f) continue;
Init_dfs (V,U,LEN+EDGE[I].CAP);
} struct Node {int id,u;
Node (int u=0,int id=0): U (u), ID (ID) {} bool operator< (const node& RHS) Const {return id < rhs.id;
}
};
Set<node> que;
typedef set<node>::iterator SET_P;
ll now = 0;
void cal (int u) {if (Que.empty ()) {Que.insert (node (u,id[u));
} set_p p = que.find (node (u,id[u)), p1, p2;
int flag =-1;
if (p = = Que.end ()) {Que.insert (node (u,id[u)));
flag = 1;
} p = Que.find (node (u,id[u])); P1 = P2 = p; Set_p ed = Que.end ();
--ed;
if (p = = Que.begin ()) p1++,p2=ed;
else if (p = = ed) p1=que.begin (), p2=ed,--p2;
else P1--, p2++;
int y = p2->u;
int x = p1->u;
now+= ((LL) D[u]-d[lca (x,u)]-d[lca (y,u)]+d[lca (x,y))) *flag; if (flag = = 1) que.eRase (P);
} int Q;
int main () {scanf ("%d%d", &n, &q);
Init ();
for (int i=0; i<n-1; i++) {int u, V, c;
scanf ("%d%d%d", &u, &v,&c);
Addedge (U, V, c);
Addedge (V, U, c);
} deg[1]=0;
Fa[1][0]=1;
DFS (1); Cnt_ = 0;
D[1] = 0;
Init_dfs (1,-1,0);
Que.clear ();
now = 0;
while (q--) {int u;
scanf ("%d", &u);
Cal (U);
printf ("%lld\n", now*2);
}
}