• POJ


    题意:给你一颗树,然后问你有多少小于k的路径

    思路:点分治入门题,网上有很多关于点分治的博客,我也看了很久的代码,想了很久。

    大概点分治就是一种通过不断找树的重心来降低复杂度的一种算法,因为数据范围很小,看其他聚聚的博客说一般点分治的题,数据范围都暗示1e4;

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int maxn=10005;
    struct edge
    {
        int to,next,w;
    }a[maxn<<1];
    int n,m,k,head[maxn],cnt;
    int root,sum,vis[maxn],sz[maxn];
    int f[maxn],dep[maxn],stk[maxn],top;
    int ans;
    void addedge(int u,int v,int w)
    {
        a[++cnt].to=v;
        a[cnt].next=head[u];
        a[cnt].w=w;
        head[u]=cnt;
    }
    void getroot(int u,int fa)
    {
        sz[u]=1;f[u]=0;
        for(int e=head[u];e;e=a[e].next){
            int v=a[e].to;
            if(v==fa||vis[v])continue;
            getroot(v,u);
            sz[u]+=sz[v];
            f[u]=max(f[u],sz[v]);
        }
        f[u]=max(f[u],sum-sz[u]);
        if(f[u]<f[root])root=u;
    }
    
    void getdep(int u,int fa)
    {
        stk[++top]=dep[u];
        for(int e=head[u];e;e=a[e].next){
            int v=a[e].to;
            if(v==fa||vis[v])continue;
            dep[v]=dep[u]+a[e].w;
            getdep(v,u);
        }
    }
    int calc(int u,int d0)
    {
        top=0;dep[u]=d0;
        getdep(u,0);
        sort(stk+1,stk+top+1);
        int l=1,r=top,res=0;
        while(l<r){
            if(stk[l]+stk[r]<=k)res+=r-l,l++;
            else r--;
        }
        return res;
    }
    
    
    void solve(int u)
    {
        ans+=calc(u,0);
        vis[u]=1;
        for(int e=head[u];e;e=a[e].next){
            int v=a[e].to;
            if(vis[v])continue;
            ans-=calc(v,a[e].w);
            sum=sz[v];root=0;
            getroot(v,0);
            solve(root);
        }
    }
    
    int main()
    {
        while(~scanf("%d%d",&n,&k)){
            if(n==0&&k==0)break;
            memset(head,0,sizeof(head));
            memset(vis,0,sizeof(vis));
            cnt=0;ans=0;
            for(int i=1;i<n;++i){
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                addedge(u,v,w);
                addedge(v,u,w);
            }
            root=0;sum=f[0]=n;
            getroot(1,0);
            solve(root);
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    指针
    初级程序员面试不靠谱指南(七)
    初级程序员面试不靠谱指南(六)
    Hadoop 中利用 mapreduce 读写 mysql 数据
    Mapreduce的文件和hbase共同输入
    mapreduce多文件输出的两方法
    mapreduce中一个map多个输入路径
    GDB介绍
    超强的指针学习笔记
    iOS开发之Appstore篇——版本更新
  • 原文地址:https://www.cnblogs.com/lalalatianlalu/p/9769743.html
Copyright © 2020-2023  润新知