zoukankan      html  css  js  c++  java
  • 【NOIP2016】运输计划

    题面

    分析

    好题。

    概括一下题意:在可以将一条边权变为0的情况下,求完成m条路线的最长时间的最小值。

    概括出来后可以明显发现是二分的标配,单调性显然,如果mid的时间是答案,比mid小的任务肯定能完成,如果有任务完不成,说明时间比mid大。

    而这m条路线又是树上边差分的暗示。

    所以很明显我们需要二分+树上差分。

    可以先在 MlogN 的时间复杂度内预处理出每条航线的路径长度,只需通过预处理每个点到根的距离再求lca即可。

    直接二分时间。将mid时间内的航线忽略,将时间比mid大的航线打上标记(把边塞给点式标记)

    最后我们只需要判断一下,所有时间比mid大的航线公共的边中,最大的那一条长度是多少。如果最长的航线减去这个长度能达成小于mid即为成立。

    虽然此题卡常,但是稍微常数优化一下,少个排序,加个读优,上register之类的,也没多大问题,至少水谷过了。。

    代码

    1. #include<bits/stdc++.h>  
    2. using namespace std;  
    3. #define N 300030  
    4. #define RT register   
    5. int n,m,l,r,cnt,num,now,mid,maxx;  
    6. int c[N],d[N],wv[N],dep[N],first[N],fa[N][20];  
    7. struct email  
    8. {  
    9.     int u,v,w;  
    10.     int nxt;  
    11. }e[N*4];  
    12. struct query  
    13. {  
    14.     int x,y,dis;  
    15. }q[N];  
    16. template<class T>  
    17. inline void read(T &x)  
    18. {  
    19.     x=0;int f=1;static char c=getchar();   
    20.     while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}  
    21.     while(c>='0'&&c<='9'){x=x*10+c-'0',c=getchar();}  
    22.     x*=f;  
    23. }  
    24. inline void add(int u,int v,int w)  
    25. {  
    26.     e[++cnt].nxt=first[u];first[u]=cnt;  
    27.     e[cnt].u=u;e[cnt].v=v;e[cnt].w=w;  
    28. }  
    29. inline void pre(int u,int f,int w)  
    30. {  
    31.     wv[u]=w;//把边塞给点   
    32.     for(RT int i=1;(1<<i)<=dep[u];++i)  
    33.         fa[u][i]=fa[fa[u][i-1]][i-1];  
    34.     for(RT int i=first[u];i;i=e[i].nxt)  
    35.     {  
    36.         int v=e[i].v,w=e[i].w;  
    37.         if(v==f)continue;  
    38.         dep[v]=dep[u]+1;  
    39.         d[v]=d[u]+w;fa[v][0]=u;  
    40.         pre(v,u,w);  
    41.     }  
    42. }  
    43.   
    44. inline int lca(int x,int y)  
    45. {  
    46.     if(dep[x]<dep[y])swap(x,y);  
    47.     int t=dep[x]-dep[y];  
    48.     for(RT int i=0;(1<<i)<=t;++i)  
    49.         if((1<<i)&t)  
    50.             x=fa[x][i];  
    51.     if(x==y)return x;  
    52.     for(RT int i=19;i>=0;--i)  
    53.         if(fa[x][i]!=fa[y][i])  
    54.             x=fa[x][i],y=fa[y][i];  
    55.     return fa[x][0];  
    56. }   
    57.   
    58. inline void dfs(int u,int f)  
    59. {  
    60.     for(RT int i=first[u];i;i=e[i].nxt)  
    61.     {  
    62.         int v=e[i].v;  
    63.         if(v==f)continue;  
    64.         dfs(v,u);  
    65.         c[u]+=c[v];   
    66.     }  
    67. }  
    68.   
    69. inline int check(int x)  
    70. {  
    71.     now=num=0;memset(c,0,sizeof(c));   
    72.     for(RT int i=1;i<=m;++i)  
    73.     {  
    74.         if(q[i].dis<=x)continue;  
    75.         ++c[q[i].x],++c[q[i].y],c[lca(q[i].x,q[i].y)]-=2;  
    76.         ++num;  
    77.     }  
    78.     dfs(1,0);  
    79.     for(RT int i=1;i<=n;++i)  
    80.         if(num==c[i])now=max(now,wv[i]);  
    81.     return maxx-now<=x;  
    82. }  
    83.   
    84. int main()  
    85. {  
    86.     read(n);read(m);  
    87.     for(RT int i=1;i<n;++i)  
    88.     {  
    89.         int u,v,w;  
    90.         read(u),read(v);read(w);  
    91.         add(u,v,w);add(v,u,w);  
    92.     }   
    93.     pre(1,0,0);  
    94.     for(RT int i=1;i<=m;++i)  
    95.     {  
    96.         read(q[i].x),read(q[i].y);  
    97.         int LCA=lca(q[i].x,q[i].y);  
    98.         q[i].dis=d[q[i].x]+d[q[i].y]-2*d[LCA];  
    99.         r=max(r,q[i].dis);  
    100.     }  
    101.     maxx=r;  
    102.     while(l<r)  
    103.     {  
    104.         mid=l+r>>1;  
    105.         if(check(mid))r=mid;  
    106.         else l=mid+1;  
    107.     }  
    108.     printf("%d ",r);  
    109.     return 0;  
    110. }  
  • 相关阅读:
    【Java】【IDE】【Jetbrain Idea】Intellij IDEA 快捷键整理
    【Linux】【Services】【KVM】virsh命令详解
    【Linux】【Services】【KVM】安装与简单配置
    【Linux】【Services】【Docker】Docker File
    【Linux】【Services】【Docker】网络
    【Linux】【Services】【Docker】应用
    【Linux】【Services】【Docker】基础理论
    【Python】【Module】json and pickle
    【Python】【Module】hashlib
    Highcharts 对数组的要求
  • 原文地址:https://www.cnblogs.com/NSD-email0820/p/9854399.html
Copyright © 2011-2022 走看看