码迷,mamicode.com
首页 > 其他好文 > 详细

codevs 1218

时间:2015-11-04 21:25:42      阅读:234      评论:0      收藏:0      [点我收藏+]

标签:

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

推到根节点后就贪心,不能再走回去且这个点需要军队而且这个点剩余的时间是从这个节点推上来的节点中最小的就走回去(语文实在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

 

codevs 1218

标签:

原文地址:http://www.cnblogs.com/onlyRP/p/4936953.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!