zoukankan      html  css  js  c++  java
  • [poj1741] tree [点分治]

    题面:

    传送门

    思路:

    树上点对信息?

    点分治啊!

    照例处理联通块信息,然后再减掉儿子里面重复的

    至于每个联通块的信息,就是把每个点到父亲的距离,小于k的放到一个数组里面,排个序,两头双指针扫一遍即可,O(nlogn)

    再加上递归层数logn,总效率O(nlognlogn)

    Code:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 inline int read(){
     7     int re=0,flag=1;char ch=getchar();
     8     while(ch>'9'||ch<'0'){
     9         if(ch=='-') flag=-1;
    10         ch=getchar();
    11     }
    12     while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
    13     return re*flag;
    14 }
    15 int n,m,cnt,root,sum,ans=0,first[10010];
    16 int d[10010],dis[10010],siz[10010],son[10010];
    17 bool vis[10010];
    18 struct edge{
    19     int to,next,w;
    20 }a[20010];
    21 inline void add(int u,int v,int w){
    22     a[++cnt]=(edge){v,first[u],w};first[u]=cnt;
    23     a[++cnt]=(edge){u,first[v],w};first[v]=cnt;
    24 }
    25 void init(){
    26     cnt=0;ans=0;memset(first,-1,sizeof(first));
    27     memset(siz,0,sizeof(siz));memset(son,0,sizeof(son));
    28     memset(dis,0,sizeof(dis));memset(vis,0,sizeof(vis));
    29 }
    30 inline int _max(int l,int r){return (l>r)?l:r;}
    31 inline int _min(int l,int r){return (l<r)?l:r;}
    32 void getroot(int u,int f){
    33     //cout<<"getroot "<<u<<" "<<f<<"
    ";
    34     int i,v;
    35     siz[u]=1;son[u]=0;
    36     for(i=first[u];~i;i=a[i].next){
    37         v=a[i].to;
    38         if(v==f||vis[v]) continue;
    39         getroot(v,u);
    40         siz[u]+=siz[v];son[u]=_max(son[u],siz[v]);
    41     }
    42     son[u]=_max(son[u],sum-siz[u]);
    43     if(son[u]<son[root]) root=u;
    44     //cout<<"finish getroot "<<u<<" "<<root<<"
    ";
    45 }
    46 void getdis(int u,int f){
    47     dis[++dis[0]]=d[u];
    48     int i,v;
    49     for(i=first[u];~i;i=a[i].next){
    50         v=a[i].to;
    51         if(v==f||vis[v]) continue;
    52         d[v]=d[u]+a[i].w;
    53         getdis(v,u);
    54     }
    55 }
    56 int calc(int u,int dd){
    57     dis[0]=0;d[u]=dd;
    58     getdis(u,0);
    59     sort(dis+1,dis+dis[0]+1);
    60     int l=1,r=dis[0],re=0;
    61     while(l<r){
    62         if(dis[l]+dis[r]<=m) re+=r-l,l++;
    63         else r--;
    64     }
    65     return re;
    66 }
    67 void dfs(int u){
    68     //cout<<"dfs "<<u<<"
    ";
    69     int i,v;vis[u]=1;
    70     ans+=calc(u,0);
    71     for(i=first[u];~i;i=a[i].next){
    72         v=a[i].to;
    73         if(vis[v]) continue;
    74         ans-=calc(v,a[i].w);
    75         sum=siz[v];root=0;
    76         getroot(v,0);
    77         dfs(root);
    78     }
    79 }
    80 int main(){
    81     //freopen("tree.in","r",stdin);
    82     int i,t1,t2,t3;
    83     while((n=read())&&(m=read())){
    84         init();
    85         for(i=1;i<n;i++){
    86             t1=read();t2=read();t3=read();
    87             add(t1,t2,t3);
    88         }
    89         sum=n;root=0;son[0]=n;
    90         getroot(1,0);
    91         dfs(root);
    92         printf("%d
    ",ans);
    93     }
    94 }
  • 相关阅读:
    bzoj 1295 [SCOI2009]最长距离 最短路
    bzoj 3669 [Noi2014]魔法森林
    bzoj 1432 [ZJOI2009]Function 思想
    用JSP输出Hello World
    Web开发基础
    JSP相关背景
    JSP概述
    Java视频播放器的制作
    为JFileChooser设定扩展名过滤
    使用JFileChooser保存文件
  • 原文地址:https://www.cnblogs.com/dedicatus545/p/8456732.html
Copyright © 2011-2022 走看看