First of all, the problem is a two-point nature, that is, the longer the time put, the more points can be cut off. Then there is the greedy verification.
Just beginning to think-for each verification, by the army depth (distance from the root) from the sorting,
1. A point in a given time can not run to the second floor, as far as possible to go up.
2. If you run to the second floor, fill in this layer.
3. If you run to the second floor and find this, you run to the root and record the time remaining.
After this, the BFS, not filled the 2nd floor by running to the root of the point to fill.
Adjusted one day, found that the idea was wrong.
Because I can make a point to fill the other points, and then let the other points back.
4
1 2 3
1 3 2
1 4 7
3
2 2 3
The answer should be 9, number 3rd, stop 4th, block 2nd, number 3rd.
The positive solution is if an army can pair with the second-level root node (a) on its own path, and if the army cannot return to a at the root, then let him be stationed in a. ID: If this army goes somewhere else x, then the Y Army comes to fill a, by the known W (A) >w (x) is obviously let Y go x, this army stationed at a best.
#include <iostream> #include <cstdio> #include <queue> #include <ctime> #include <cstring
> #include <algorithm> #define MAXN 50005 #define LL Long long using namespace std;
int n,m;
struct e{int to,nxt;
LL D;
}B[MAXN*2];
int Fst[maxn],tot;
void Insert (int f,int t,ll d) {b[++tot]= (E) {t,fst[f],d};fst[f]=tot;
B[++tot]= (E) {f,fst[t],d};fst[t]=tot;
} LL DIS[MAXN];
int fa[maxn][20];
int TOP[MAXN];
int PE[MAXN];
BOOL CMP (int a,int b) {if (Dis[a]!=dis[b]) return dis[a]>dis[b];
Return a<b;
} bool ISF[MAXN];
int SZ[MAXN];
void Dfs (int x,int p) {top[x]=p;
for (int i=1;i<=16;i++) fa[x][i]=fa[fa[x][i-1]][i-1];
for (int i=fst[x];i;i=b[i].nxt) {int v=b[i].to;
if (!fa[v][0]) {fa[v][0]=x;
DIS[V]=DIS[X]+B[I].D;
DFS (v,p); sz[x]++;
}} if (!sz[x]) isf[x]=true;
} bool VIS[MAXN];
int nd[maxn],c;
Queue<int> Q; void BFs (LL mid) {Q.PUsh (1);
C=0;vis[1]=1; while (! Q.empty ()) {int U=q.front ();
Q.pop ();
for (int i=fst[u];i;i=b[i].nxt) {int v=b[i].to;
if (!vis[v]) {if (Isf[v]) nd[++c]=top[v];
else Q.push (v);
Vis[v]=1;
}}} sort (nd+1,nd+c+1,cmp);
C=unique (nd+1,nd+c+1)-nd-1;
} LL Stack[maxn];int Top; BOOL Check (LL mid) {memset (vis,0,sizeof (VIS));
Top=0;
for (int i=1;i<=m;i++) {int u=pe[i];int v=top[u];
LL Cst=dis[u]-dis[v]; if (vis[v]| |
Dis[u]+dis[v]<=mid) {LL p=mid-dis[u];
Stack[++top]=p;
} else if (Cst<=mid) vis[v]=1; else {int p=u;
LL Res=mid;
for (int j=16;j>=0;j--) {int w=fa[p][j];
LL Wv=dis[p]-dis[w];
if (wv<=res) {P=W;RES-=WV;} } while (sZ[FA[P][0]]==1&&!VIS[P]) vis[p]=1,p=fa[p][0];
Vis[p]=1;
}} BFS (mid);
int h=1;
for (int i=c;i>=1;i--) {LL p=dis[nd[i]];
while (Stack[h]<p&&h<=top) h++; if (h>top) return false;
h++;
} return true;
} int main () {scanf ("%d", &n); int u,v;
LL D;
int cnt=0;
for (int i=1;i<n;i++) {scanf ("%d%d%lld", &u,&v,&d);
Insert (U,V,D); if (u==1| |
V==1) cnt++;
} for (int i=0;i<=18;i++) fa[1][i]=1;
for (int i=fst[1];i;i=b[i].nxt) {int v=b[i].to;
DIS[V]=B[I].D;
Fa[v][0]=1;
DFS (V,V);
} scanf ("%d", &m);
for (int i=1;i<=m;i++) scanf ("%d", &pe[i]);
Sort (pe+1,pe+m+1,cmp);
if (m<cnt) {puts ("-1");
return 0;
} LL L=-1,r=1e9,mid;
while (r-l>1) {mid= (l+r) >>1;
if (check (mid)) R=mid; else L=mid;
} cout<<r<<endl; }