• codevs 1218


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

    推到根节点后就贪心,不能再走回去且这个点需要军队而且这个点剩余的时间是从这个节点推上来的节点中最小的就走回去(语文实在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
    ",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
    ",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
    ",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
    ",r);
    110     return 0;
    111 }
    View Code
  • 相关阅读:
    帮同事整理的 C# 调用 C++ 回调函数
    解决VS2010下使用NUnit 无法进行调试的问题
    Linux /var/log/messages 偶尔会发生time reset +6.288863s
    linux设置静态路由
    os auto installtion
    read 在bash ksh下的不同表现
    C#编码规范1
    C#中new一个对象时,发生了什么事?
    C# 实例化类的执行顺序
    C#类注释规范
  • 原文地址:https://www.cnblogs.com/onlyRP/p/4936953.html
Copyright © 2020-2023  润新知