• POJ 1741 Tree


    http://poj.org/problem?id=1741

    点分治QAQ,测了20min

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define INF 0x7fffffff
    const int maxn = 10007;
    inline int read() {
        int x=0;char c=getchar();
        while(c<'0'||c>'9') c=getchar();
        while(c<='9'&&c>='0')x=x*10+c-'0',c=getchar();
        return x;
    }
    int n,k;
    bool vis[maxn];
    int sum,ans,root,num;
    int head[10005],deep[10005],dis[10005],f[10005],son[10005];
    struct node{
        int v,next,w;
    }edge[maxn<<1];
    void add_edge(int u,int v,int w) {
        edge[++num].v=v;edge[num].w=w;edge[num].next=head[u];head[u]=num;
    }
    void getroot(int x,int fa) {
        son[x]=1;f[x]=0;
        for(int i=head[x];i;i=edge[i].next) {
            int v=edge[i].v;
            if(v==fa||vis[v])continue;
            getroot(v,x);
            son[x]+=son[v];
            f[x]=std::max(f[x],son[v]);
        }
        f[x]=std::max(f[x],sum-son[x]);
        if(f[x]<f[root])root=x;
    }
    void getdeep(int x,int fa) {
        deep[++deep[0]]=dis[x];
        for(int i=head[x];i;i=edge[i].next) {
            int v=edge[i].v;
            if(v==fa||vis[v])continue;
            dis[v]=dis[x]+edge[i].w;
            getdeep(v,x);
        }
    }
    int calc(int x,int now) {
        dis[x]=now;deep[0]=0;
        getdeep(x,0);
        std::sort(deep+1,deep+deep[0]+1);
        int t=0;
        for(int l=1,r=deep[0];l<r;) {
            if(deep[l]+deep[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];i;i=edge[i].next) {
            int v=edge[i].v;
            if(vis[v])continue;
            ans-=calc(v,edge[i].w);
            sum=son[v];
            root=0;
            getroot(v,root);
            work(root);
        }
    }
    int main() {
        while(11101001) {
            ans=0;num=0;root=0;
            n=read(),k=read();
            if(!n&&!k)break;
            std::memset(vis,0,sizeof vis);
            std::memset(head,0,sizeof head);
            for(int a,b,c,i=1;i<n;++i) {
                a=read(),b=read(),c=read();
                add_edge(a,b,c);
                add_edge(b,a,c);
            }
            sum=n;f[0]=INF;
            getroot(1,0);
            work(root);
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    二叉树的构造与遍历
    最长公共子序列
    Python爬虫与数据图表的实现
    降维实例之主成分分析
    数据集之转换器以及估计器
    机器学习算法分类以及开发流程
    数据的降维之特征选择及主成分分析
    特征工程之归一化及标准化
    文本tfidf
    文本特征抽取
  • 原文地址:https://www.cnblogs.com/sssy/p/8157182.html
Copyright © 2020-2023  润新知