码迷,mamicode.com
首页 > 其他好文 > 详细

[BZOJ 1468][POJ 1741]Tree

时间:2018-01-11 22:27:27      阅读:197      评论:0      收藏:0      [点我收藏+]

标签:hid   isp   技术分享   return   img   计算   problem   col   poj   

[BZOJ 1468][POJ 1741]Tree

 

<题意概括>

给定一棵树,求有多少对满足两两距离不超过k的点对(u,v)

 

<做法>

典型的点分治题目

找出当前树的重心

计算该顶点到其子树中每个顶点的路径长度

使用双指针法统计满足条件的路径条数并减去那些在同一棵子树中的路径

删除该顶点并递归处理每一棵子树

 

<Code> 

技术分享图片
#include<cstdio>
#include<cstring>
#include<algorithm>
#define Fast register
#define INF 2147483647
inline int Max(const int&x,const int&y){return x>y?x:y;}

inline char Getchar(){
    static char BUF[16384],*S=BUF,*T=BUF;
    return(S==T)&&(T=(S=BUF)+fread(BUF,1,16384,stdin),S==T)?EOF:*S++;
}
inline int Getint(){
    Fast int s=0;Fast char c=Getchar();
    while(c<48||c>57)c=Getchar();
    while(c>47&&c<58)s=s*10+c-48,c=Getchar();
    return s;
}

struct Edge{
    int to,v;Edge*next;
    Edge(const int&T,const int&V,Edge*&N):to(T),v(V),next(N){}
}*Front[40001];
#define AddEdge(x,y,z) Front[x]=new Edge(y,z,Front[x])
int root;
int Size[40001];
int MaxSize[40001];
int Recent_Node;
bool vis[40001];
int Distance[40001];
int Dis[40001];
int Cnt_Dis;
int N,DisLimit;
int Ans;

inline void FindBarycenter(const int&now,const int&Fa){
    Size[now]=1;MaxSize[now]=0;
    for(Fast Edge*o=Front[now];o!=NULL;o=o->next){
        if(o->to!=Fa&&!vis[o->to]){
            FindBarycenter(o->to,now);
            Size[now]+=Size[o->to];
            MaxSize[now]=Max(MaxSize[now],Size[o->to]);
        }
    }
    MaxSize[now]=Max(MaxSize[now],Recent_Node-Size[now]);
    if(MaxSize[now]<MaxSize[root])root=now;
}
inline void Cal_Dis(const int&now,const int&Fa){
    Dis[++Cnt_Dis]=Distance[now];
    for(Fast Edge*o=Front[now];o!=NULL;o=o->next){
        if(o->to!=Fa&&!vis[o->to]){
            Distance[o->to]=Distance[now]+o->v;
            Cal_Dis(o->to,now);
        }
    }
}
inline int Calculate(const int&now,const int&DisNow){
    Distance[now]=DisNow,Cnt_Dis=0;
    Cal_Dis(now,0);
    std::sort(Dis+1,Dis+Cnt_Dis+1);
    Fast int L=1,R=Cnt_Dis,Num=0;
    while(L<R)Dis[L]+Dis[R]<=DisLimit?Num+=R-L,++L:--R;
    return Num;
}
inline void Slove(const int&now){
    Ans+=Calculate(now,0),vis[now]=true;
    for(Fast Edge*o=Front[now];o!=NULL;o=o->next){
        if(!vis[o->to]){
            Ans-=Calculate(o->to,o->v);
            root=0;
            Recent_Node=Size[o->to];
            FindBarycenter(o->to,now);
            Slove(root);
        }
    }
}
int main(){
    N=Getint();
    for(Fast int i=1;i<N;++i){
        Fast int u=Getint(),v=Getint(),l=Getint();
        AddEdge(u,v,l);AddEdge(v,u,l);
    }
    DisLimit=Getint();
    MaxSize[root=0]=INF;
    Recent_Node=N;
    FindBarycenter(1,0);
    Slove(root);
    printf("%d\n",Ans);
    return 0;
}
[BZOJ 1468]Tree 
技术分享图片
#include<cstdio>
#include<cstring>
#include<algorithm>
#define Fast register
#define INF 2147483647
inline int Max(const int&x,const int&y){return x>y?x:y;}

inline char Getchar(){
    static char BUF[16384],*S=BUF,*T=BUF;
    return(S==T)&&(T=(S=BUF)+fread(BUF,1,16384,stdin),S==T)?EOF:*S++;
}
inline int Getint(){
    Fast int s=0;Fast char c=Getchar();
    while(c<48||c>57)c=Getchar();
    while(c>47&&c<58)s=s*10+c-48,c=Getchar();
    return s;
}

struct Edge{
    int to,v;Edge*next;
    Edge(const int&T,const int&V,Edge*&N):to(T),v(V),next(N){}
}*Front[10001];
#define AddEdge(x,y,z) Front[x]=new Edge(y,z,Front[x])
int root;
int Size[10001];
int MaxSize[10001];
int Recent_Node;
bool vis[10001];
int Distance[10001];
int Dis[10001];
int Cnt_Dis;
int N,DisLimit;
int Ans;

inline void FindBarycenter(const int&now,const int&Fa){
    Size[now]=1;MaxSize[now]=0;
    for(Fast Edge*o=Front[now];o!=NULL;o=o->next){
        if(o->to!=Fa&&!vis[o->to]){
            FindBarycenter(o->to,now);
            Size[now]+=Size[o->to];
            MaxSize[now]=Max(MaxSize[now],Size[o->to]);
        }
    }
    MaxSize[now]=Max(MaxSize[now],Recent_Node-Size[now]);
    if(MaxSize[now]<MaxSize[root])root=now;
}
inline void Cal_Dis(const int&now,const int&Fa){
    Dis[++Cnt_Dis]=Distance[now];
    for(Fast Edge*o=Front[now];o!=NULL;o=o->next){
        if(o->to!=Fa&&!vis[o->to]){
            Distance[o->to]=Distance[now]+o->v;
            Cal_Dis(o->to,now);
        }
    }
}
inline int Calculate(const int&now,const int&DisNow){
    Distance[now]=DisNow,Cnt_Dis=0;
    Cal_Dis(now,0);
    std::sort(Dis+1,Dis+Cnt_Dis+1);
    Fast int L=1,R=Cnt_Dis,Num=0;
    while(L<R)Dis[L]+Dis[R]<=DisLimit?Num+=R-L,++L:--R;
    return Num;
}
inline void Slove(const int&now){
    Ans+=Calculate(now,0);vis[now]=true;
    for(Fast Edge*o=Front[now];o!=NULL;o=o->next){
        if(!vis[o->to]){
            Ans-=Calculate(o->to,o->v);
            root=0;
            Recent_Node=Size[o->to];
            FindBarycenter(o->to,now);
            Slove(root);
        }
    }
}
int main(){
    while(N=Getint(),DisLimit=Getint(),N||DisLimit){
        Recent_Node=N;
        memset(Front,NULL,sizeof Front);
        memset(vis,false,sizeof vis);
        for(Fast int i=1;i<N;++i){
            Fast int u=Getint(),v=Getint(),l=Getint();
            AddEdge(u,v,l);AddEdge(v,u,l);
        }
        MaxSize[Ans=root=0]=INF;
        FindBarycenter(1,0);
        Slove(root);
        printf("%d\n",Ans);
    }
    return 0;
}
[POJ 1741]Tree 

[BZOJ 1468][POJ 1741]Tree

标签:hid   isp   技术分享   return   img   计算   problem   col   poj   

原文地址:https://www.cnblogs.com/Trisolaris/p/BZOJ-1468.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!