zoukankan      html  css  js  c++  java
  • [BZOJ2599]Race

    Description

    给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000

    Input

    第一行 两个整数 n, k
    第二..n行 每行三个整数 表示一条无向边的两端和权值 (注意点的编号从0开始)

    Output

    一个整数 表示最小边数量 如果不存在这样的路径 输出-1

    Sample Input

    4 3
    0 1 1
    1 2 2
    1 3 4

    Sample Output

    2

    HINT

     2018.1.3新加数据一组,未重测

    Source

    很简单的一道点分治,注意一下维护的顺序,先更新答案再更新桶数组

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #define M 200010
     5 using namespace std;
     6 int n,m,num,rt,ans,k,S;
     7 int maxn[M],head[M],dis[M],d[M],size[M],t[M<<3];
     8 bool vis[M];
     9 struct point{int to,next,dis;}e[M<<1];
    10 void add(int from,int to,int dis) {
    11     e[++num].next=head[from];
    12     e[num].to=to;
    13     e[num].dis=dis;
    14     head[from]=num;
    15 }
    16 void getroot(int x,int fa) {
    17     size[x]=1;maxn[x]=0;
    18     for(int i=head[x];i;i=e[i].next) {
    19         int to=e[i].to;
    20         if(to==fa||vis[to]) continue;
    21         getroot(to,x),size[x]+=size[to];
    22         maxn[x]=max(maxn[x],size[to]);
    23     }
    24     maxn[x]=max(maxn[x],S-size[x]);
    25     if(maxn[x]<maxn[rt]) rt=x;
    26 }
    27 void cal(int x,int fa) {
    28     if(dis[x]>k) return;
    29     ans=min(ans,d[x]+t[k-dis[x]]);
    30     for(int i=head[x];i;i=e[i].next) {
    31         int to=e[i].to;
    32         if(vis[to]||to==fa) continue;
    33         d[to]=d[x]+1,dis[to]=dis[x]+e[i].dis;
    34         cal(to,x);
    35     }
    36 }
    37 void insert(int x,int fa) {
    38     if(dis[x]<=k) {
    39         t[dis[x]]=min(t[dis[x]],d[x]);
    40         for(int i=head[x];i;i=e[i].next)
    41             if(!vis[e[i].to]&&e[i].to!=fa)
    42                 insert(e[i].to,x);
    43     }
    44 }
    45 void del(int x,int fa) {
    46     if(dis[x]<=k) {
    47         t[dis[x]]=1e9;
    48         for(int i=head[x];i;i=e[i].next)
    49             if(!vis[e[i].to]&&e[i].to!=fa)
    50                 del(e[i].to,x);
    51     }
    52 }
    53 void solve(int x) {
    54     vis[x]=true;t[0]=0;
    55     for(int i=head[x];i;i=e[i].next) {
    56         int to=e[i].to;
    57         if(vis[to]) continue;
    58         d[to]=1,dis[to]=e[i].dis,cal(to,0);
    59         insert(to,x);
    60     }
    61     for(int i=head[x];i;i=e[i].next)
    62         if(!vis[e[i].to])
    63             del(e[i].to,x);
    64     for(int i=head[x];i;i=e[i].next) {
    65         int to=e[i].to;
    66         if(vis[to]) continue;
    67         rt=0,S=size[to],getroot(to,0);
    68         solve(rt);
    69     }
    70 }
    71 int main() {
    72     scanf("%d%d",&n,&k);ans=n+1;
    73     memset(t,1,sizeof(t));
    74     for(int i=1;i<n;i++) {
    75         int a,b,c;scanf("%d%d%d",&a,&b,&c);
    76         a++,b++;
    77         add(a,b,c),add(b,a,c);
    78     }
    79     S=maxn[0]=n;getroot(1,0);
    80     solve(rt);
    81     if(ans>n) puts("-1");
    82     else printf("%d
    ",ans);
    83     return 0;
    84 }
  • 相关阅读:
    THUSC2016 成绩单 和 LOJ3226 Greedy Pie Eaters
    LOJ3215 Muzyka pop
    LOJ3223 Trzy kule
    ZJOI2015 幻想乡战略游戏 和 SCOI2019 找重心
    LOJ3235 Przedszkole 和 有限空间跳跃理论
    SCOI2019 湖之精灵的游戏
    SCOI2016 幸运数字
    SCOI2014 方伯伯的商场之旅
    POJ3621 Sightseeing Cows 和 CH6B12 最优高铁环 和 SCOI2014 方伯伯运椰子
    SCOI2014 方伯伯的OJ 和 NOIP2017 列队
  • 原文地址:https://www.cnblogs.com/Slrslr/p/10027299.html
Copyright © 2011-2022 走看看