zoukankan      html  css  js  c++  java
  • 【BZOJ2599】Race(点分治)

    题意:给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.

    N <= 200000, K <= 1000000

    思路:跟着高中学长李日天(迪克李)的课件复习一下树分治

    https://wenku.baidu.com/view/ae220cc0ed630b1c58eeb5b3.html

    也算是自己第一道独立完成的点分治,纪念一下

    From https://www.cnblogs.com/candy99/p/6270581.html

    小总结:

    目前遇到的点分治处理有两种:

    1.先统计每颗子树,处理一颗子树时使用了之前子树的信息
    2.先统计整棵树然后减去同一棵子树里的,可以只一遍邻接链表循环

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<string>
      4 #include<cmath>
      5 #include<iostream>
      6 #include<algorithm>
      7 #include<map>
      8 #include<set>
      9 #include<queue>
     10 #include<vector>
     11 using namespace std;
     12 typedef long long ll;
     13 typedef unsigned int uint;
     14 typedef unsigned long long ull;
     15 typedef pair<int,int> PII;
     16 typedef vector<int> VI;
     17 #define fi first
     18 #define se second s
     19 #define MP make_pair
     20 #define N   410000
     21 #define M   1100000
     22 #define MOD 1000000007
     23 #define eps 1e-8 
     24 #define pi acos(-1)
     25 #define oo 1e9
     26 
     27 int q[N][2],head[N],vet[N],nxt[N],len[N],dis[N],dep[N],flag[N],son[N],c[N],
     28     f[M],n,tot,top,ans,sum,root,K;
     29 
     30 
     31 
     32 int read()
     33 { 
     34    int v=0,f=1;
     35    char c=getchar();
     36    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
     37    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
     38    return v*f;
     39 }
     40 
     41 void add(int a,int b,int c)
     42 {
     43     nxt[++tot]=head[a];
     44     vet[tot]=b;
     45     len[tot]=c;
     46     head[a]=tot;
     47 }
     48 
     49 void getroot(int u,int fa)
     50 {
     51     son[u]=1; c[u]=0;
     52     int e=head[u];
     53     while(e)
     54     {
     55         int v=vet[e];
     56         if(v!=fa&&!flag[v])
     57         {
     58             getroot(v,u);
     59             son[u]+=son[v];
     60             c[u]=max(c[u],son[v]);
     61         }
     62         e=nxt[e];
     63     }
     64     c[u]=max(c[u],sum-c[u]);
     65     if(c[u]<c[root]) root=u;
     66 }
     67 
     68 void dfs(int u,int fa)
     69 {
     70     q[++top][1]=dis[u];
     71     q[top][2]=dep[u];
     72     int e=head[u];
     73     while(e)
     74     {
     75         int v=vet[e];
     76         if(v!=fa&&!flag[v])
     77         {
     78             dep[v]=dep[u]+1;
     79             dis[v]=dis[u]+len[e];
     80             dfs(v,u);
     81         }
     82         e=nxt[e];
     83     }
     84 }
     85 
     86 void work(int u)
     87 {
     88     flag[u]=1; f[0]=0; dep[u]=1;
     89     int e=head[u];
     90     while(e)
     91     {
     92         int v=vet[e];
     93         if(!flag[v])
     94         {
     95             top=0; 
     96             dis[v]=len[e]; 
     97             dep[v]=1;
     98             dfs(v,u);
     99             for(int i=1;i<=top;i++)
    100             { 
    101                 int t=K-q[i][1];
    102                 if(t>=0&&t<=K) ans=min(ans,q[i][2]+f[t]);
    103             }
    104             ans=min(ans,f[K]);
    105             for(int i=1;i<=top;i++) 
    106              if(q[i][1]>=0&&q[i][1]<=K) f[q[i][1]]=min(f[q[i][1]],q[i][2]);
    107         }
    108         e=nxt[e];    
    109     }
    110     
    111     e=head[u];
    112     while(e)
    113     {
    114         int v=vet[e];
    115         if(!flag[v])
    116         {
    117             top=0; 
    118             dis[v]=len[e]; 
    119             dep[v]=1;
    120             dfs(v,u);
    121             for(int i=1;i<=top;i++) 
    122              if(q[i][1]>=0&&q[i][1]<=K) f[q[i][1]]=oo;
    123         }
    124         e=nxt[e];    
    125     }
    126 
    127     e=head[u];
    128     while(e)
    129     {
    130         int v=vet[e];
    131         if(!flag[v])
    132         {
    133             sum=son[v]; root=0;
    134             getroot(v,0);
    135             work(root);
    136         }
    137         e=nxt[e];
    138     }
    139 }
    140 
    141 int main()
    142 {
    143     //freopen("bzoj2599.in","r",stdin);
    144     //freopen("bzoj2599.out","w",stdout);
    145     scanf("%d%d",&n,&K);
    146     for(int i=1;i<=n-1;i++)
    147     {
    148         int x,y,z;
    149         scanf("%d%d%d",&x,&y,&z);
    150         x++; y++;
    151         add(x,y,z);
    152         add(y,x,z);
    153     }
    154     root=0; sum=n; c[0]=n; 
    155     ans=oo;
    156     for(int i=0;i<=K;i++) f[i]=oo;
    157     getroot(1,0);
    158     work(root);
    159     if(ans>n) printf("-1
    ");
    160      else printf("%d
    ",ans);
    161     return 0;
    162 }
    163     
    164     
    165 
    166 
    167             
    168         
  • 相关阅读:
    怎样应对突发性的开发需求
    ASP.NET过滤HTML标签只保留换行与空格的方法
    sqlserver 各种判断是否存在(表名、函数、存储过程等)
    Timing advance of GSM(时间提前量)
    对.NET中Hashtable和ArryList的理解
    GPS原始经纬度转百度经纬度
    baidu经纬度坐标与google经纬度坐标都转换
    .NET资料之-根据两点经纬度计算直线距离
    .net处理JSON简明教程
    在asp.net中要不使用其他插件的情况下只能使用定时器来检查, 并执行任务.
  • 原文地址:https://www.cnblogs.com/myx12345/p/9710738.html
Copyright © 2011-2022 走看看