• POJ 1741 Tree


    Tree
    Time Limit: 1000MS   Memory Limit: 30000K
    Total Submissions: 20124   Accepted: 6613

    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

    Source

    IOI论文下载

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define m(x) memset(x,0,sizeof x)
    using namespace std;
    int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9') ch=getchar();
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x;
    }
    const int N=1e4+10;
    struct node{
        int v,w,next;
    }e[N<<1];
    int n,K,tot,root,sum,ans,head[N],son[N],f[N],d[N],dep[N];
    bool vis[N];
    void add(int x,int y,int z){
        e[++tot].v=y;e[tot].w=z;e[tot].next=head[x];head[x]=tot;
        e[++tot].v=x;e[tot].w=z;e[tot].next=head[y];head[y]=tot;
    } 
    void get_root(int x,int fa){//寻找重心 
    //重心,就是删掉此结点后,剩下的结点最多的树结点个数最小
        son[x]=1;f[x]=0;
        for(int i=head[x],v;i;i=e[i].next){
            if((v=e[i].v)==fa||vis[v]) continue;
            get_root(v,x);
            son[x]+=son[v];
            f[x]=max(f[x],son[v]); 
        }
        f[x]=max(f[x],sum-son[x]);
        if(f[x]<f[root]) root=x;
    }
    void get_deep(int x,int fa){
        dep[++dep[0]]=d[x];
        for(int i=head[x],v;i;i=e[i].next){
            if((v=e[i].v)==fa||vis[v]) continue;
            d[v]=d[x]+e[i].w;
            get_deep(v,x);
        }
    }
    int calc(int x,int now){
        d[x]=now;dep[0]=0;
        get_deep(x,0);
        sort(dep+1,dep+dep[0]+1);
        int t=0,l,r;
        for(l=1,r=dep[0];l<r;){
            if(dep[l]+dep[r]<=K){t+=r-l;l++;}
            else r--;
        }
        return t;
    }
    void work(int x){//分治 
        ans+=calc(x,0);
        vis[x]=1;
        for(int i=head[x],v;i;i=e[i].next){
            if(vis[v=e[i].v]) continue;
            ans-=calc(v,e[i].w);
            sum=son[v];
            get_root(v,root=0);
            work(root);
        }
    }
    void Cl(){
        ans=0;tot=0;root=0;
        m(head);m(vis);
    }
    int main(){
        while(Cl(),n=read(),K=read()){
            for(int i=1,x,y,z;i<n;i++) x=read(),y=read(),z=read(),add(x,y,z);
            sum=n;f[0]=0x7fffffff;
            get_root(1,0);
            work(root);
            printf("%d
    ",ans);
        }
        return 0;
    }

     UPD.2017-05-05

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define m(s) memset(s,0,sizeof s);
    using namespace std;
    template <typename T>
    inline void read(T &x){
        register char ch=getchar();x=0;
        while(ch<'0'||ch>'9') ch=getchar();
        while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    }
    const int N=1e4+5;
    int n,k,ans,sum,root;
    int siz[N],f[N],d[N],dep[N];bool vis[N];
    struct edge{int v,w,next;}e[N<<1];int tot,head[N];
    inline void add(int x,int y,int z){
        e[++tot].v=y;e[tot].w=z;e[tot].next=head[x];head[x]=tot;
        e[++tot].v=x;e[tot].w=z;e[tot].next=head[y];head[y]=tot;
    }
    void findroot(int x,int fa){
        siz[x]=1;f[x]=0;
        for(int i=head[x];i;i=e[i].next){
            if(e[i].v==fa||vis[e[i].v]) continue;
            findroot(e[i].v,x);
            siz[x]+=siz[e[i].v];
            f[x]=max(f[x],siz[e[i].v]);
        }
        f[x]=max(f[x],sum-siz[x]);
        if(f[x]<f[root]) root=x;
    }
    void getdep(int x,int fa){
        dep[++dep[0]]=d[x];
        for(int i=head[x];i;i=e[i].next){
            if(e[i].v==fa||vis[e[i].v]) continue;
            d[e[i].v]=d[x]+e[i].w;
            getdep(e[i].v,x);
        }
    }
    inline int calc(int x,int w){
        d[x]=w;dep[0]=0;getdep(x,0);
        stable_sort(dep+1,dep+dep[0]+1);
        int res=0;
        for(int l=1,r=dep[0];l<r;) if(dep[l]+dep[r]<=k) res+=r-l++;else r--;
        return res;
    }
    void solve(int x){
        ans+=calc(x,0);
        vis[x]=1;
        for(int i=head[x];i;i=e[i].next){
            if(vis[e[i].v]) continue;
            ans-=calc(e[i].v,e[i].w);
            f[root=0]=sum=siz[e[i].v];
            findroot(e[i].v,0);
            solve(root);
        }
    }
    inline void clr(){
        tot=0;m(head);m(vis);
    }
    int main(){
        for(read(n),read(k);n&&k;read(n),read(k),clr()){
            for(int i=1,x,y,z;i<n;i++) read(x),read(y),read(z),add(x,y,z);
            f[root=0]=sum=n;findroot(1,0);
            ans=0;solve(root);
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    1054 The Dominant Color (20 分)
    1120 Friend Numbers (20 分)
    19. JSP
    18. Javaweb中文件的上传和下载【重要】
    8. 颜色和样式
    clear 清除浮动 CSS
    17. JSP
    Session
    16. JSP 过滤器解决Post编码【乱码】问题
    HTML <form> 标签的 的 属性
  • 原文地址:https://www.cnblogs.com/shenben/p/6269606.html
Copyright © 2020-2023  润新知