zoukankan      html  css  js  c++  java
  • POJ1741 Tree

    点分治模板题。

    男人必做八题。

    每棵子树统计经过根节点的满足情况个数,再减去子树中不经过根节点的情况个数,类似于一个容斥。复杂度O(Nlog^2N)

    注意每次getroot所定的树的大小是改变的,不能一直是n否则会退化。

    By:大奕哥

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<algorithm>
     5 #include<cstring>
     6 using namespace std;
     7 const int N=10005;
     8 struct node
     9 {
    10     int to,nex,w;
    11 }e[N<<1];
    12 int head[N],f[N],cnt,v[N],s[N],d[N],n,k,rt,num,ans,maxn;
    13 void add(int x,int y,int w)
    14 {
    15     e[++cnt].to=y;e[cnt].w=w;e[cnt].nex=head[x];head[x]=cnt;
    16 }
    17 void getrt(int x,int fa)
    18 {
    19     s[x]=1;f[x]=0;
    20     for(int i=head[x];i;i=e[i].nex)
    21     {
    22         int y=e[i].to;
    23         if(y==fa||v[y])continue;
    24         getrt(y,x);s[x]+=s[y];
    25         f[x]=max(f[x],s[y]);
    26     }
    27     f[x]=max(f[x],maxn-s[x]);
    28     if(f[x]<f[rt])rt=x;
    29     return;
    30 }
    31 void dfsd(int x,int w,int fa)
    32 {
    33     d[++num]=w;
    34     for(int i=head[x];i;i=e[i].nex)
    35     {
    36         int y=e[i].to;
    37         if(y==fa||v[y])continue;
    38         dfsd(y,w+e[i].w,x);
    39     }
    40 }
    41 int calc(int x,int w)
    42 {
    43     num=0;dfsd(x,w,0);int pre=0;
    44     sort(d+1,d+1+num);
    45     int j=num;
    46     for(int i=1;i<j;++i)
    47     {
    48         while(i<j&&d[i]+d[j]>k)--j;
    49         pre+=j-i;
    50     }
    51     return pre;
    52 }
    53 void dfs(int x)
    54 {
    55     v[x]=1;ans+=calc(x,0);
    56     for(int i=head[rt];i;i=e[i].nex)
    57     {
    58         int y=e[i].to;
    59         if(!v[y])
    60         {
    61             ans-=calc(y,e[i].w);
    62             rt=0,maxn=s[y];getrt(y,0);
    63             dfs(rt);
    64         }
    65     }
    66 }
    67 int main()
    68 {
    69     while(~scanf("%d%d",&n,&k))
    70     {
    71         if(!n&&!k)break;
    72         int x,y,w;
    73         memset(head,0,sizeof(head));cnt=0;
    74         memset(v,0,sizeof(v));ans=0;
    75         for(int i=1;i<n;++i)
    76         {
    77             scanf("%d%d%d",&x,&y,&w);
    78             add(x,y,w);add(y,x,w);
    79         }
    80         rt=0,f[rt]=n;maxn=n;
    81         getrt(1,0);
    82         dfs(rt);
    83         printf("%d
    ",ans);
    84     }
    85 }
  • 相关阅读:
    动手动脑
    选课1.0
    四则运算
    JAVA异常处理机制资料整理
    JAVA学习日报(快乐作业) 10.27
    JAVA学习日报(快乐作业) 10.20
    JAVA学习日报 9/30
    JAVA学习日报 9/28
    JAVA学习日报 9/27
    JAVA学习日报 9/26
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8087331.html
Copyright © 2011-2022 走看看