zoukankan      html  css  js  c++  java
  • HDU多校2020 第十场 1005/6881-Tree Cutting(点分治

    题意:http://acm.hdu.edu.cn/showproblem.php?pid=6881

    求直径为k的树最多包多少点

    思路:

    一开始直接上了动态点分治,甚至傻乎乎得上了树状数组,其实搞个数组计个前缀和就够了,但是又开了主席树空间不够,也是TLE,还卡栈空间

    看了std发现可以从外到内直接统计贡献,很类似树DP,分成在外面的和在里面两种,边有点不太一样,我还一度认为是和点一样的调了好久,这题似乎读入不多,读入挂没什么用

      1 unordered_map<ll,int>mp;
      2 int k,ek;
      3 int dep[N],Dep[N],id[N];
      4 int max_dep[N];
      5 int selfcnt[N],soncnt[N];
      6 int ansnode[N],ansedge[N];
      7 class TREEDiv
      8 {
      9 public:
     10     bool vis[N];
     11     int sz[N],stk[N],anc[N],top,MX;
     12     int rt,respart;
     13     void Init(int n)
     14     {
     15         for(int i=0;i<=n;++i)vis[i]=0;
     16     }
     17     void get_gravity(int u,int f,int S)
     18     {
     19         sz[u]=1;
     20         int max_part=0;
     21         for(int i=head[u];i;i=edge[i].next)
     22         {
     23             int to=edge[i].to;
     24             if(to==f||vis[to])continue;
     25             get_gravity(to,u,S);
     26             sz[u]+=sz[to];
     27             max_part=max(max_part,sz[to]);
     28         }
     29         max_part=max(max_part,S-sz[u]);
     30         if(max_part<respart)
     31         {
     32             respart=max_part;
     33             rt=u;
     34         }
     35     }
     36     void get_self(int u,int f,int depth)
     37     {
     38         max_dep[rt]=max(max_dep[rt],depth);
     39         dep[u]=depth;
     40         selfcnt[depth]++;
     41         sz[u]=1;
     42         for(int i=head[u];i;i=edge[i].next)
     43         {
     44             int to=edge[i].to;
     45             if(to==f||vis[to])continue;
     46             get_self(to,u,depth+1);
     47             sz[u]+=sz[to];
     48         }
     49     }
     50     void get_son(int u,int f)
     51     {
     52         MX=max(MX,dep[u]);
     53         soncnt[dep[u]]++;
     54         stk[++top]=u;
     55         anc[u]=f;
     56         for(int i=head[u];i;i=edge[i].next)
     57         {
     58             int to=edge[i].to;
     59             if(to==f||vis[to])continue;
     60             get_son(to,u);
     61         }
     62     }
     63     void workson(int u,int f)
     64     {
     65         MX=0;top=0;
     66         get_son(u,f);
     67         for(int i=2;i<=MX;++i)soncnt[i]+=soncnt[i-1];
     68         ansedge[Dep[u]>Dep[f]?id[u]:id[f]]+=soncnt[min(ek+1,MX)];
     69         for(int i=1;i<=top;++i)
     70         {
     71             int to=stk[i];
     72             if(k>=dep[to])
     73                 ansnode[to]+=selfcnt[min(k-dep[to],max_dep[f])]-soncnt[min(k-dep[to],MX)];
     74             if(ek>=dep[to]-1)
     75                 ansedge[Dep[to]>Dep[anc[to]]?id[to]:id[anc[to]]]+=selfcnt[min(ek-dep[to]+1,max_dep[f])]-soncnt[min(ek-dep[to]+1,MX)];
     76         }
     77         for(int i=1;i<=MX;++i)soncnt[i]=0;
     78     }
     79     void solve(int u,int f)
     80     {
     81         vis[u]=1;
     82         get_self(u,f,0);
     83         for(int i=1;i<=max_dep[u];++i)selfcnt[i]+=selfcnt[i-1];
     84         ansnode[u]+=selfcnt[min(k,max_dep[u])];
     85 //        if(f!=0)ansedge[Dep[u]>Dep[f]?id[u]:id[f]]+=selfcnt[min(ek,max_dep[u]+(Dep[u]>Dep[f]?-1:0))];
     86         for(int i=head[u];i;i=edge[i].next)
     87         {
     88             int to=edge[i].to;
     89             if(vis[to])continue;
     90             workson(to,u);
     91         }
     92         for(int i=0;i<=max_dep[u];++i)selfcnt[i]=0;
     93         for(int i=head[u];i;i=edge[i].next)
     94         {
     95             int to=edge[i].to;
     96             if(vis[to])continue;
     97             respart=inf;//ans是找rt用的
     98             get_gravity(to,0,sz[to]);
     99             solve(rt,u);
    100         }
    101     }
    102     //====================题目函数
    103 }TrDiv;
    104 
    105 void TotInit(int n){
    106     for(int i=0;i<=n;++i)ansedge[i]=ansnode[i]=max_dep[i]=0;
    107     Init(n);
    108     TrDiv.Init(n);
    109 }
    110 int ttt;
    111 int el[N],er[N];
    112 void Dfs(int u,int f)
    113 {
    114     Dep[u]=Dep[f]+1;
    115     for(int i=head[u];i;i=edge[i].next)
    116     {
    117         int to=edge[i].to;
    118         if(to==f)continue;
    119         Dfs(to,u);
    120         id[to]=edge[i].id;
    121     }
    122 }
    123 void solve()
    124 {
    125     mp.clear();
    126     ttt++;
    127     int n;
    128     FI(n),FI(k);
    129     ek=(k-1)/2;
    130     k/=2;
    131     TotInit(n);
    132     for(int i=1;i<n;++i)
    133     {
    134         int u,v;
    135         FI(u),FI(v);
    136     //    if(u>v)swap(u,v);
    137         add(u,v,i);
    138         add(v,u,i);
    139     //    el[i]=u,er[i]=v;
    140     //    mp[1ll*1000000*v+u]=i;
    141     }
    142     Dfs(1,0);
    143     TrDiv.respart=inf;
    144     TrDiv.get_gravity(1,0,n);
    145     int rt=TrDiv.rt;
    146     TrDiv.solve(rt,0);
    147     int ans=0;
    148     for(int i=1;i<=n;++i)ans=max(ans,ansnode[i]);
    149     for(int i=1;i<n;++i)ans=max(ans,ansedge[i]);
    150     FO(n-ans);
    151     FO('
    ');
    152 }
  • 相关阅读:
    vue实例讲解之vuex的使用
    实例讲解webpack的基本使用第一篇
    如何写一个jquery插件
    《改变你一生的108个心理学法则》读书笔记
    用css绘制各种图形
    关于js浮点数计算精度不准确问题的解决办法
    非常有用的css使用总结
    网页meta标签总结
    Object.defineProperty()方法的用法详解
    js中set和get的用法
  • 原文地址:https://www.cnblogs.com/--HPY-7m/p/13548621.html
Copyright © 2011-2022 走看看