zoukankan      html  css  js  c++  java
  • POJ 3162 Walking Race 树形dp 优先队列

    题意 :  一棵n个节点的树。wc爱跑步,跑n天,第i天从第i个节点开始跑步,每次跑到距第i个节点最远的那个节点(产生了n个距离),现在要在这n个距离里取连续的若干天,使得这些天里最大距离和最小距离的差小于M,问怎么取使得天数最多?

     
    每个点的最大距离和之前http://acm.hdu.edu.cn/showproblem.php?pid=2196这道题一样
    (就是求每个子树的最长子链,次长子链,然后求经过父亲节点能达到的最大值,比较一下)
     
    嗯求最长连续天数这个显然n^2是不现实的,但是连续什么的会想起很久以前似曾相识的一道优先队列题...然后强行一个大根堆一个小根堆,l和r适当情况下右移,复杂度n就可以a了...
      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #include<algorithm>
      5 #include<cmath>
      6 #include<queue>
      7 using namespace std;
      8 #define pa pair<long long,int>
      9 const int maxn=1000010;
     10 int n,m;
     11 priority_queue< pa,vector< pa >,less< pa > >q1;
     12 priority_queue< pa,vector< pa >,greater< pa > >q2;
     13 struct nod{
     14     int y;
     15     long long v;
     16     int next;
     17 }e[maxn*2];
     18 int vis[maxn]={};
     19 long long f[maxn][3]={}; //0父亲 1最长 2次长
     20 long long ma[maxn]={};
     21 int f1[maxn][3]={};
     22 int head[maxn]={};
     23 int tot=0;
     24 void init(int x,int y,long long v){
     25     e[++tot].y=y;
     26     e[tot].v=v;
     27     e[tot].next=head[x];
     28     head[x]=tot;
     29 }
     30 void dfs(int x){
     31     int y;
     32     vis[x]=1;
     33     long long tmp=0;
     34     for(int i=head[x];i;i=e[i].next){
     35         y=e[i].y;
     36         tmp=e[i].v;
     37         if(!vis[y]){
     38             dfs(y);
     39             tmp+=f[y][1];
     40             if(tmp>f[x][1]){
     41                 f[x][2]=f[x][1];
     42                 f1[x][2]=f1[x][1];
     43                 f[x][1]=tmp;
     44                 f1[x][1]=y;
     45             }
     46             else if(tmp>f[x][2]){
     47                 f[x][2]=tmp;
     48                 f1[x][2]=y;
     49             }
     50         }
     51     }
     52 }
     53 void dfs2(int x,int fa,long long v){
     54     int y;
     55     long long tmp;
     56     vis[x]=1;
     57     if(f1[fa][1]==x){
     58         f[x][0]=v+max(f[fa][0],f[fa][2]);
     59     }
     60     else{
     61         f[x][0]=v+max(f[fa][0],f[fa][1]);
     62     }
     63     ma[x]=max(f[x][0],f[x][1]);
     64     for(int i=head[x];i;i=e[i].next){
     65         y=e[i].y;
     66         tmp=e[i].v;
     67         if(!vis[y]){
     68             dfs2(y,x,tmp);
     69         }
     70     }
     71 }
     72 long long mab(long long x){
     73     if(x<0){
     74         return -x;
     75     }
     76     return x;
     77 }
     78 int main(){
     79     scanf("%d%d",&n,&m);
     80     int y;
     81     long long v;
     82     for(int i=1;i<n;i++){
     83         scanf("%d%lld",&y,&v);
     84         init(i+1,y,v);
     85         init(y,i+1,v);
     86     }dfs(1);
     87     memset(vis,0,sizeof(vis));
     88     dfs2(1,0,0);
     89     int ans=0;
     90     int l=1,r=0;
     91     for(int i=1;i<=n;i++){
     92         q1.push(make_pair(ma[i],i));
     93         q2.push(make_pair(ma[i],i));
     94         r++;
     95         int id1=q1.top().second,id2=q2.top().second;
     96         while(id1<l){
     97             q1.pop();
     98             id1=q1.top().second;
     99         }
    100         while(id2<l){
    101             q2.pop();
    102             id2=q2.top().second;
    103         }
    104         long long z1=q1.top().first,z2=q2.top().first;
    105         while(mab(z1-z2)>=m){
    106             l++;
    107             while(id1<l){
    108                 q1.pop();
    109                 id1=q1.top().second;
    110             }
    111             while(id2<l){
    112                 q2.pop();
    113                 id2=q2.top().second;
    114             }
    115             z1=q1.top().first,z2=q2.top().first;
    116         }ans=max(ans,r-l+1);
    117     }
    118     cout<<ans<<endl;
    119     return 0;
    120 }
    View Code
  • 相关阅读:
    有效获取状态栏(StatusBar)高度
    各种数据库连接
    Spring AOP 原理
    Spring ioc 原理
    转载的别人的ajax跨域解决方法
    如何监听input的脚本赋值
    JAVA之Socket编程
    JAVA中的多线程
    JAVA文件操作
    实验三 kali下metasploit的漏洞攻击实践
  • 原文地址:https://www.cnblogs.com/137shoebills/p/7783906.html
Copyright © 2011-2022 走看看