zoukankan      html  css  js  c++  java
  • BZOJ 2599 Race(树分治)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2599

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

    题意:每次找到当前树的重心作为树根,查找通过当前树根的路径。

      1 #include<algorithm>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<cstring>
      5 #include<iostream>
      6 #include<ctime>
      7 int tot,go[1000005],next[1000005],first[1000005],val[1000005];
      8 int size[1000005],F[1000005],cnt[1000005],a[1000005],root,n,K,vis[1000005];
      9 int dis[1000005],ans,sz,h[1000005],sum;
     10 long long sx;
     11 int read(){
     12     char ch=getchar();int t=0,f=1;
     13     while (ch<'0'||ch>'9') {
     14         if (ch=='-') f=-1;
     15         ch=getchar();
     16     }
     17     while ('0'<=ch&&ch<='9'){
     18         t=t*10+ch-'0';
     19         ch=getchar();
     20     }
     21     return t*f;
     22 }
     23 void insert(int x,int y,int z){
     24     tot++;
     25     go[tot]=y;
     26     next[tot]=first[x];
     27     first[x]=tot;
     28     val[tot]=z;
     29 }
     30 void add(int x,int y,int z){
     31     insert(x,y,z);
     32     insert(y,x,z);
     33 }
     34 void findroot(int x,int fa){
     35     size[x]=1;F[x]=0;
     36     for (int i=first[x];i;i=next[i]){
     37         int pur=go[i];
     38         if (pur==fa||vis[pur]) continue;
     39         findroot(pur,x);
     40         size[x]+=size[pur];
     41         F[x]=std::max(F[x],size[pur]);
     42     }
     43     F[x]=std::max(F[x],sum-size[x]);
     44     if (F[root]>F[x]) root=x;
     45 }
     46 void dfs1(int x,int fa){
     47     sx++;
     48     if (dis[x]>K) return;
     49     if (h[K-dis[x]]==sz) ans=std::min(ans,a[K-dis[x]]+cnt[x]);
     50     for (int i=first[x];i;i=next[i]){
     51         int pur=go[i];
     52         if (pur==fa||vis[pur]) continue;
     53         cnt[pur]=cnt[x]+1;
     54         dis[pur]=dis[x]+val[i];
     55         dfs1(pur,x);
     56     }
     57 }
     58 void dfs2(int x,int fa){
     59     if (dis[x]>K) return;
     60     if (h[dis[x]]!=sz) h[dis[x]]=sz,a[dis[x]]=cnt[x];
     61     else a[dis[x]]=std::min(a[dis[x]],cnt[x]);
     62     for (int i=first[x];i;i=next[i]){
     63         int pur=go[i];
     64         if (pur==fa||vis[pur]) continue;
     65         dfs2(pur,x);
     66     }
     67 }
     68 int find(int x,int fa){
     69     int all=1;
     70     for (int i=first[x];i;i=next[i]){
     71         int pur=go[i];
     72         if (pur==fa||vis[pur]) continue;
     73         all+=find(pur,x);
     74     }
     75     return all;
     76 }
     77 void query(int x){
     78     h[0]=++sz;
     79     a[0]=0;
     80     vis[x]=1;
     81     for (int i=first[x];i;i=next[i]){
     82         int pur=go[i];
     83         if (vis[pur]) continue;
     84         dis[pur]=val[i];
     85         cnt[pur]=1;
     86         dfs1(pur,x);
     87         dfs2(pur,x);
     88     }
     89     for (int i=first[x];i;i=next[i]){
     90         int pur=go[i];
     91         if (vis[pur]) continue;
     92         root=0;
     93         sum=find(pur,0);
     94         findroot(pur,0);
     95         query(root);
     96     }
     97 }
     98 int main(){
     99     n=read();K=read();
    100     for (int i=1;i<n;i++){
    101         int x,y,z;
    102         x=read();
    103         y=read();
    104         z=read();
    105         x++;y++;
    106         add(x,y,z);
    107     }
    108     root=0;
    109     F[0]=n+1;
    110     ans=n;
    111     sum=n;
    112     findroot(1,0);
    113     query(root);
    114     if (ans==n) ans=-1;
    115     printf("%d
    ",ans);
    116 }
  • 相关阅读:
    python之编写购物车(第二天)
    day6作业--游戏人生
    day7 socket网络编程基础
    day7 --socket网络编程基础
    Python类和人类
    day7 socket网络编程
    day7异常处理
    day7面向对象--反射
    day6面向对象--类的特殊成员方法
    使用BigDecimal来进行精确计算
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5537889.html
Copyright © 2011-2022 走看看