只想到二分答案,每次先用倍增将点推上去。。。

推到根节点后就贪心,不能再走回去且这个点需要军队而且这个点剩余的时间是从这个节点推上来的节点中最小的就走回去(语文实在LJ。。。)

实现起来貌似很难但代码不是很长

第二次用到set了,做得比较慢。。。不学C艹真的会死得很惨。。。

WA一个点不造是怎么回事。。

  1 #include<bits/stdc++.h>
  2 #define inc(i,l,r) for(i=l;i<=r;i++)
  3 #define dec(i,l,r) for(i=l;i>=r;i--)
  4 #define mem(a) memset(a,0,sizeof(a))
  5 #define inf 1e9
  6 #define ll long long
  7 #define succ(x) (1<<x)
  8 #define NM 80000+5
  9 using namespace std;
 10 int read(){
 11     int x=0,f=1;char ch=getchar();
 12     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
 13     while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
 14     return x*f;
 15 }
 16 struct edge{
 17     int t;
 18     ll v;
 19     edge *next;
 20 }e[2*NM],*h[NM];
 21 int f[NM][30],p=25,i,k,n,m,_x,_y,s,ff[NM],minn[NM];
 22 ll l,r,_t,b[NM],c[NM],d[NM][30],a[NM];
 23 bool v[NM],leaf[NM];
 24 multiset<ll>S;
 25 multiset<ll>::iterator it;
 26 void add(int x,int y,ll v){
 27     e[++s].t=y;e[s].v=v;e[s].next=h[x];h[x]=e+s;
 28 }
 29 void dfs(int x){
 30     v[x]++;
 31     inc(i,1,p){
 32         f[x][i]=f[f[x][i-1]][i-1];
 33         d[x][i]=d[f[x][i-1]][i-1]+d[x][i-1];
 34     }
 35     for(edge *j=h[x];j;j=j->next)
 36     if(!v[j->t]){
 37         leaf[x]=true;
 38         f[j->t][0]=x;
 39         d[j->t][0]=j->v;
 40         if(x==1){
 41         ff[j->t]=j->t;
 42         c[j->t]=j->v;
 43         }else ff[j->t]=ff[x];
 44         dfs(j->t);
 45     }
 46 }
 47 bool _dfs(int x,int k){
 48     if(!leaf[x]&&!v[x])return false;
 49     for(edge *j=h[x];j;j=j->next)
 50     if(j->t!=k&&!v[j->t])
 51     if(!_dfs(j->t,x))return false;
 52     return true;
 53 }
 54 bool check(){
 55     mem(v);mem(minn);mem(b);
 56     int num=0,tot=0;
 57     inc(i,1,m){
 58         ll t=_t,tmp=a[i];
 59         dec(k,p,0)
 60         if(t>=d[tmp][k]){
 61             t-=d[tmp][k];
 62             tmp=f[tmp][k];
 63         }
 64         if(tmp<=1){
 65             b[++tot]=t;
 66             if(t<=c[ff[a[i]]]&&(!minn[ff[a[i]]]||t<b[minn[ff[a[i]]]]))
 67             minn[ff[a[i]]]=tot;
 68         }else v[tmp]++;
 69     }
 70     for(edge *j=h[1];j;j=j->next)
 71     if(!v[j->t])v[j->t]=_dfs(j->t,1);
 72     inc(i,1,n)
 73     if(!v[i]&&minn[i])
 74     b[minn[i]]=0,v[i]++;
 75     sort(b+1,b+1+tot);
 76     S.clear();
 77 //    S.insert(-inf);S.insert(inf);
 78 //    printf("%d\n",S.size());
 79     for(edge *j=h[1];j;j=j->next)
 80     if(!v[j->t]){
 81     S.insert(j->v);
 82 //    printf("%d\n",S.size());
 83     }
 84     inc(i,1,tot)
 85     if(b[i]){
 86         it=S.upper_bound(b[i]);
 87         if(it==S.begin())continue;
 88         it--;
 89         S.erase(it);
 90 //        printf("%d\n",S.size());
 91         if(S.empty())return true;
 92     }
 93     return false;
 94  }
 95 int main(){
 96     n=read();
 97     inc(i,1,n-1){
 98         _x=read();_y=read();scanf("%lld",&_t);
 99         add(_x,_y,_t);add(_y,_x,_t);
100     }
101     dfs(1);
102     m=read();
103     inc(i,1,m)a[i]=read();
104     l=0;r=n*inf;
105     while(l+1<r){
106         _t=l+r>>1;
107         if(check())r=_t;else l=_t;
108     }
109     printf("%lld\n",r);
110     return 0;
111 }
View Code

 

posted on 2015-11-04 19:00  onlyRP  阅读(122)  评论(0编辑  收藏  举报