#include<bits/stdc++.h>
#define MAXN 70005
using namespace std;
int n,h[MAXN],tot,ff[MAXN][25],cost[MAXN][25],m,g[MAXN],l,r,mid,best,sum[MAXN],f[MAXN];
int found[MAXN],vis[MAXN],al;
struct node{
int from,to,cost,next;
}e[MAXN << 1];
int js,js2;
struct node2{
int ch,rest;
}q[MAXN],q2[MAXN];
bool cmp(int x , int y){
return cost[x][0] < cost[y][0];
}
bool cmp2(node2 x , node2 y){
return x.rest - cost[x.ch][0] < y.rest - cost[y.ch][0];
}
bool cmp3(node2 x , node2 y){
return x.rest - cost[x.ch][0] > y.rest - cost[y.ch][0];
}
/*
¨¬¡ãD?1?¡ê¡Á¡è?¨¹¡Á¨®¨º¡Â??¡ä¨®¡ê???¨®?
??¡¤¡§¡êo?t¡¤?¡äe¡ã?+¨¦????D??
?t¡¤?????¨°??¨¦?¨´D¨¨¡Á?¨¦¨´¨º¡À??
??¡Á¨¦?¨¹?¨®??¨¢|¨ª¨´?¨´?¨²¦Ì?¡Á?
¨¢????¨²¦Ì?¡êo1¡ê??¨¦¨°?¦Ì??¨´?¨²¦Ì? 2¡ê?2??¨¦¨°?¦Ì??¨´?¨²¦Ì?
1¡ê?¦Ì??¨´?¨²¦Ì?¨º¡À¡ê????¡è?????¨²¦Ì?¦Ì??¨´?¨²¦Ì??¨´¡Á¨®?¨´¨º¡ê??¦Ì?¨º¡À??¨°??¡ã?¨´¨º??¨´¡Á¨®
2, ??¨¢|¨ª¨´¨¦?¡Á??¨ªDD¨¢?
check¡êo
?¨¨¡ä|¨¤¨ª2¨¤¨¤?¨²¦Ì?¡ê?¨º¡Â?¡ã¡Áo¡ê?¦Ì?¦Ì?????¨°?¡Á¨®??¨®D¡À??2??¡ê?¦Ì?¦Ì????¨´¨º?¦Ì??¨´?¨´¡Á¨®¡Á¨®¨º¡Â
*/
void add(int x , int y , int z){
tot++;
e[tot].from = x;
e[tot].to = y;
e[tot].cost = z;
e[tot].next = h[x];
h[x] = tot;
}
void get(int now , int fa){
ff[now][0] = fa;
int kk = 0;
for(int i = h[now] ; i != (-1) ; i = e[i].next){
if(e[i].to == fa)continue;
kk++;
}
for(int i = h[now] ; i != (-1) ; i = e[i].next){
if(e[i].to == fa)continue;
cost[e[i].to][0] = e[i].cost;
if(kk == 1)f[e[i].to] = f[now];
else f[e[i].to] = e[i].to;
get(e[i].to , now);
}
}
void init(){
memset(h , -1 , sizeof(h));tot = 0;
memset(cost , 0 , sizeof(cost));
cin>>n;int u,v,w;
for(int i = 1 ; i < n ; i++){
cin>>u>>v>>w;
add(u , v , w) , add(v , u , w);
}
for(int i = h[1] ; i != (-1) ; i = e[i].next)f[e[i].to] = e[i].to;
get(1 , 1);
for(int j = 1 ; j <= 23 ; j++)
for(int i = 1 ; i <= n ; i++)
ff[i][j] = ff[ff[i][j - 1]][j - 1];
for(int j = 1 ; j <= 23 ; j++)
for(int i = 1 ; i <= n ; i++)
cost[i][j] = cost[i][j - 1] + cost[ff[i][j - 1]][j - 1];
}
int check(int dx){
for(int i = 1 ; i <= n ; i++)sum[i] = 0;
int zz,now;al = js = js2 = 0;
for(int i = 1 ; i <= m ; i++){
zz = dx , now = g[i];
for(int j = 23 ; j >= 0 ; j--)
if(cost[now][j] <= zz && ff[now][j] != 1)
zz -= cost[now][j] , now = ff[now][j];
if(ff[now][0] == 1 && zz >= cost[now][0])q[++js].ch = now , q[js].rest = zz - cost[now][0];
else sum[f[now]]++;
}
sort(q + 1 , q + 1 + js , cmp2);
for(int i = 1 ; i <= js ; i++){
if(sum[q[i].ch] == 0 && q[i].rest < cost[q[i].ch][0])sum[q[i].ch]++;
else q2[++js2] = q[i];
}
for(int i = h[1] ; i != (-1) ; i = e[i].next)if(!sum[e[i].to])found[++al] = e[i].to;
swap(q , q2) , swap(js , js2);
sort(found + 1 , found + 1 + al , cmp);
sort(q + 1 , q + 1 + js , cmp2);
zz = 1 , now = 1;
while(zz <= al && now <= js){
if(q[now].rest >= cost[found[zz]][0]){
zz++ , now++;
}
else now++;
}
if(zz > al)return 1;
else return 0;
return 1;
}
void solve(){
cin>>m;
for(int i = 1 ; i <= m ; i++)cin>>g[i];
l = 0 , r = 50000000 , best = (-1);
check(9);
while(l <= r){
mid = (l + r) >> 1;
if(check(mid))r = mid - 1 , best = mid;
else l = mid + 1;
}
cout<<best<<endl;
}
int main(){
init();
solve();
}
做法1 O ( n l o g 2 n ) O(nlog^2n) O(nlog2n)直接二分,然后全部往上跳,然后再在根节点处理一下就好了
做法2
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)直接先处理出每个军队到根节点的距离再排序,然后可以二分到那个节点可以上根,然后就复杂的处理一下。。。。。打是不可能打的