zoukankan      html  css  js  c++  java
  • POJ1741 Tree

    POJ1741 Tree
    Time Limit: 1000MS   Memory Limit: 30000K
    Total Submissions: 6232   Accepted: 1770

    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
    ----------------------------------------------------------------
    题目大意:见漆子超论文。
    解题思路:见漆子超论文。表示一A,爽歪歪,原来是这样子的,还是觉得挺暴力的,只是避免了最坏情况而已。
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <queue>
    #define clr(a,b) memset(a,b,sizeof(a))
    using namespace std;
    
    const int N=10005,M=20005,inf=0x3f3f3f3f;
    int n,lim,eid,minn;
    int head[N],ed[M],val[M],nxt[M];
    int vis[N],fa[N],siz[N],dep[N],le,ri;
    
    void addedge(int s,int e,int v){
        ed[eid]=e;val[eid]=v;nxt[eid]=head[s];head[s]=eid++;
    }
    
    int dfssize(int s,int f){
        fa[s]=f;siz[s]=1;
        for(int i=head[s];~i;i=nxt[i])
            if(ed[i]!=f&&!vis[ed[i]])siz[s]+=dfssize(ed[i],s);
        return siz[s];
    }
    
    void dfsroot(int s,int sum,int&root){
        int maxx=sum-siz[s];
        for(int i=head[s];~i;i=nxt[i]){
            int e=ed[i];if(e==fa[s]||vis[e])continue;
            dfsroot(e,sum,root);maxx=max(maxx,siz[e]);
        }
        if(maxx<minn){minn=maxx;root=s;}
    }
    
    void dfsdepth(int s,int d,int f){
        dep[ri++]=d;
        for(int i=head[s];~i;i=nxt[i])
            if(ed[i]!=f&&!vis[ed[i]])dfsdepth(ed[i],d+val[i],s);
    }
    
    int getdep(int a,int b){
        sort(dep+a,dep+b);int ret=0,e=b-1;
        for(int i=a;i<b;i++){
            if(dep[i]>lim)break;
            while(e>=a&&dep[e]+dep[i]>lim)e--;
            ret+=e-a+1;if(e>i)ret--;
        }
        return ret>>1;
    }
    
    int solve(int s){
        int sum=dfssize(s,-1),ret=0;minn=inf;
        int root;dfsroot(s,sum,root);
        vis[root]=1;
        for(int i=head[root];~i;i=nxt[i])
            if(ed[i]!=root&&!vis[ed[i]])
                ret+=solve(ed[i]);
        le=ri=0;
        for(int i=head[root];~i;i=nxt[i])
            if(ed[i]!=root&&!vis[ed[i]]){
                dfsdepth(ed[i],val[i],-1);ret-=getdep(le,ri);le=ri;
            }
        ret+=getdep(0,ri);
        for(int i=0;i<ri;i++)
            if(dep[i]<=lim)ret++;
            else break;
    //    printf("%d %d %d %d\n",root,ret,le,ri);
        vis[root]=0;
        return ret;
    }
    
    int main(){
    //    freopen("/home/axorb/in","r",stdin);
        while(scanf("%d%d",&n,&lim),n+lim){
            eid=0;clr(head,-1);
            for(int i=1;i<n;i++){
                int a,b,c;scanf("%d%d%d",&a,&b,&c);
                addedge(a,b,c);addedge(b,a,c);
            }
            clr(vis,0);
            printf("%d\n",solve(1));
        }
    }
    

      

    也许有挫折,但这些,怎能挡住湘北前进的步伐
  • 相关阅读:
    思维导图
    网络面经
    2.17 C++ 专项练习 错题复盘
    C++面经
    2.15 C++专项练习 错题复盘
    uboot下读取flash,上传tftp服务器、下载
    Hi3516EV100烧录出厂固件
    用Hi3518EV200板当spi烧录器
    生而为人,我很抱歉!深夜爬虫, 我很抱歉 ,附微信 “ 网抑云” 公众号爬虫教程!
    阿里HR: 你会 Android 实现侧滑菜单-design吗? CN看了,原来这么简单呀!
  • 原文地址:https://www.cnblogs.com/Fatedayt/p/2580555.html
Copyright © 2011-2022 走看看