• BZOJ2599: [IOI2011]Race


    n<=200000的边权树上问长度=K<=1000000的链中边数最少的。

    点分治。开个桶统计各个长度的答案。

     1 #include<string.h>
     2 #include<stdlib.h>
     3 #include<stdio.h>
     4 #include<math.h>
     5 #include<algorithm>
     6 //#include<bitset>
     7 //#include<queue>
     8 //#include<iostream>
     9 using namespace std;
    10 
    11 int n,K;
    12 #define maxn 200011
    13 #define maxk 1000011
    14 struct Edge{int to,v,next;}edge[maxn<<1]; int first[maxn],le=2;
    15 void in(int x,int y,int v) {Edge &e=edge[le]; e.to=y; e.v=v; e.next=first[x]; first[x]=le++;}
    16 void insert(int x,int y,int v) {in(x,y,v); in(y,x,v);}
    17 
    18 int size[maxn]; bool die[maxn];
    19 void getsize(int x,int fa)
    20 {
    21     size[x]=1;
    22     for (int i=first[x];i;i=edge[i].next)
    23     {
    24         const Edge &e=edge[i]; if (e.to==fa || die[e.to]) continue;
    25         getsize(e.to,x); size[x]+=size[e.to];
    26     }
    27 }
    28 
    29 int getroot(int x,int fa,int tot)
    30 {
    31     for (int i=first[x];i;i=edge[i].next)
    32     {
    33         const Edge &e=edge[i]; if (e.to==fa || die[e.to]) continue;
    34         if (size[e.to]*2>tot) return getroot(e.to,x,tot);
    35     }
    36     return x;
    37 }
    38 
    39 int f[maxk];
    40 void calc(int x,int fa,int now,int cur)
    41 {
    42     if (now>K) return;
    43     f[K]=min(f[K],f[K-now]+cur);
    44     for (int i=first[x];i;i=edge[i].next)
    45     {
    46         const Edge &e=edge[i]; if (e.to==fa || die[e.to]) continue;
    47         calc(e.to,x,now+e.v,cur+1);
    48     }
    49 }
    50 
    51 void gao(int x,int fa,int now,int v,bool op)
    52 {
    53     if (now>K) return;
    54     if (op) f[now]=min(f[now],v);
    55     else (now!=K && (f[now]=0x3f3f3f3f));
    56     for (int i=first[x];i;i=edge[i].next)
    57     {
    58         const Edge &e=edge[i]; if (e.to==fa || die[e.to]) continue;
    59         gao(e.to,x,now+e.v,v+1,op);
    60     }
    61 }
    62 
    63 void cd(int x)
    64 {
    65     die[x]=1; f[0]=0;
    66     for (int i=first[x];i;i=edge[i].next)
    67     {
    68         const Edge &e=edge[i]; if (die[e.to]) continue;
    69         calc(e.to,x,e.v,1); gao(e.to,x,e.v,1,1);
    70     }
    71     for (int i=first[x];i;i=edge[i].next)
    72     {
    73         const Edge &e=edge[i]; if (die[e.to]) continue;
    74         gao(e.to,x,e.v,0,0);
    75     }
    76     for (int i=first[x];i;i=edge[i].next)
    77     {
    78         const Edge &e=edge[i]; if (die[e.to]) continue;
    79         getsize(e.to,x); cd(getroot(e.to,x,size[e.to]));
    80     }
    81 }
    82 
    83 int main()
    84 {
    85     scanf("%d%d",&n,&K);
    86     for (int i=1,x,y,v;i<n;i++)
    87     {
    88         scanf("%d%d%d",&x,&y,&v); x++; y++;
    89         insert(x,y,v);
    90     }
    91     getsize(1,0);
    92     for (int i=1;i<=K;i++) f[i]=0x3f3f3f3f;
    93     cd(getroot(1,0,size[1]));
    94     printf("%d
    ",f[K]==0x3f3f3f3f?-1:f[K]);
    95     return 0;
    96 }
    View Code
  • 相关阅读:
    ubuntu中,update,upgrade出现问题总结
    Xshell7连接kali linux(2021.9.13)
    pycharm安装igraph,简单实例(2021.8.21)
    mininet可视化(2021.6.25)
    冷知识:你会搜索信息吗
    论文写作注意事项
    onenote2016怎么自动备份笔记本到本地?
    Cbench、Scapy、sflow、iperf——学习中
    Zookeeper、Docker——学习中
    OpenStack管理、KVM、ClouldSim部署——学习中
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8350690.html
Copyright © 2020-2023  润新知