zoukankan      html  css  js  c++  java
  • POJ1741 Tree + BZOJ1468 Tree 【点分治】

    POJ1741 Tree + BZOJ1468 Tree


    Description

    Give a tree with n vertices,each edge has a length(positive integer less than 1001).
    Define dist(u,v)=The min distance between node u and v.
    Give an integer k,for every pair (u,v) of vertices is called valid if and only if dist(u,v) not exceed k.
    Write a program that will count how many pairs which are valid for a given tree.

    Input

    The input contains several test cases. The first line of each test case contains two integers n, k. (n<=10000) The following n-1 lines each contains three integers u,v,l, which means there is an edge between node u and v of length l.
    The last test case is followed by two zeros.

    Output

    For each test case output the answer on a single line.

    Sample Input

    5 4
    1 2 3
    1 3 1
    1 4 2
    3 5 1
    0 0

    Sample Output

    8


    BZOJ上的和POJ上的其实差不多,只是输入输出格式的区别

    然后就是点分治的板子
    但是dcy说这题卡常,我也不知道为什么

    我也没有卡啊


    POJ1741:

    #include<iostream>
    #include<vector>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define N 40010
    int n,k,cnt,rt,siz_tree,ans;
    int siz[N],F[N],dis[N],head[N],val[N];
    bool vis[N];
    struct Edge{int v,w,next;}E[N<<1];
    void init(){
        cnt=0;ans=0;
        memset(head,0,sizeof(head));
        memset(dis,0,sizeof(dis));
        memset(vis,0,sizeof(vis));//******
    }
    void add(int u,int v,int w){
        cnt++;
        E[cnt].v=v;
        E[cnt].w=w;
        E[cnt].next=head[u];
        head[u]=cnt;
    }
    void getroot(int u,int fa){
        siz[u]=1;F[u]=0;
        for(int i=head[u];i;i=E[i].next){
            int v=E[i].v;
            if(vis[v]||v==fa)continue;
            getroot(v,u);
            siz[u]+=siz[v];
            F[u]=max(F[u],siz[v]);
        }
        F[u]=max(F[u],siz_tree-siz[u]);
        if(F[u]<F[rt])rt=u;
    }
    void getdis(int u,int fa){
        val[++val[0]]=dis[u];
        for(int i=head[u];i;i=E[i].next){
            int v=E[i].v;
            if(v==fa||vis[v])continue;
            dis[v]=dis[u]+E[i].w;
            getdis(v,u);
        }
    }
    int work(int u,int pre){
        val[0]=0;dis[u]=pre;
        getdis(u,0);
        sort(val+1,val+val[0]+1);
        int l=1,r=val[0],res=0;
        while(l<r){
            if(val[r]+val[l]<=k)res+=r-l,l++;
            else r--;
        }
        return res;
    }
    void solve(int u){
        ans+=work(u,0);
        vis[u]=1;
        for(int i=head[u];i;i=E[i].next){
            int v=E[i].v;
            if(vis[v])continue;
            ans-=work(v,E[i].w);
            F[rt=0]=siz_tree=siz[v];
            getroot(v,0);
            solve(rt);
        }
    }
    int main(){
        while(1){
            scanf("%d%d",&n,&k);
            if(!n&&!k)return 0;
            init();
            for(int i=1;i<n;i++){
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                add(u,v,w);
                add(v,u,w);
            }
            F[rt=0]=siz_tree=n;
            getroot(1,0);
            solve(rt);
            printf("%d
    ",ans);
        }
        return 0;
    }

    BZOJ1468:

    #include<iostream>
    #include<vector>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define N 40010
    int n,k,cnt,rt,siz_tree,ans;
    int siz[N],F[N],dis[N],head[N],val[N];
    bool vis[N];
    struct Edge{int v,w,next;}E[N<<1];
    void init(){
        cnt=0;ans=0;
        memset(head,0,sizeof(head));
        memset(dis,0,sizeof(dis));
        memset(vis,0,sizeof(vis));//******
    }
    void add(int u,int v,int w){
        cnt++;
        E[cnt].v=v;
        E[cnt].w=w;
        E[cnt].next=head[u];
        head[u]=cnt;
    }
    void getroot(int u,int fa){
        siz[u]=1;F[u]=0;
        for(int i=head[u];i;i=E[i].next){
            int v=E[i].v;
            if(vis[v]||v==fa)continue;
            getroot(v,u);
            siz[u]+=siz[v];
            F[u]=max(F[u],siz[v]);
        }
        F[u]=max(F[u],siz_tree-siz[u]);
        if(F[u]<F[rt])rt=u;
    }
    void getdis(int u,int fa){
        val[++val[0]]=dis[u];
        for(int i=head[u];i;i=E[i].next){
            int v=E[i].v;
            if(v==fa||vis[v])continue;
            dis[v]=dis[u]+E[i].w;
            getdis(v,u);
        }
    }
    int work(int u,int pre){
        val[0]=0;dis[u]=pre;
        getdis(u,0);
        sort(val+1,val+val[0]+1);
        int l=1,r=val[0],res=0;
        while(l<r){
            if(val[r]+val[l]<=k)res+=r-l,l++;
            else r--;
        }
        return res;
    }
    void solve(int u){
        ans+=work(u,0);
        vis[u]=1;
        for(int i=head[u];i;i=E[i].next){
            int v=E[i].v;
            if(vis[v])continue;
            ans-=work(v,E[i].w);
            F[rt=0]=siz_tree=siz[v];
            getroot(v,0);
            solve(rt);
        }
    }
    int main(){
        scanf("%d",&n);
        init();
        for(int i=1;i<n;i++){
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);
            add(v,u,w);
        }
        scanf("%d",&k);
        F[rt=0]=siz_tree=n;
        getroot(1,0);
        solve(rt);
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    哪种可以让程序员赚到更多钱?
    layer 弹框 很好用 页面交互不好弄!!!父子弹框的交互!
    博客导航
    扯淡扯着扯着就远了----关键字;宁静致远
    高驰涛——裸奔到北京的程序猿
    TP5分页类使用——超级简单好用
    七牛云同步资源工具使用说明
    短链接实现原理和简单调用
    抓包工具Charles下载地址及Charles配置https
    敲代码的少年
  • 原文地址:https://www.cnblogs.com/dream-maker-yk/p/9676314.html
Copyright © 2011-2022 走看看