zoukankan      html  css  js  c++  java
  • LG P4149 [IOI2011]Race

    Description

    给一棵树,每条边有权。求一条简单路径,权值和等于 $k$,且边的数量最小。

    Solution

    点分治,统计答案时只统计经过该节点的所有链(包括以该节点为端点)

    每次用桶维护之前的子树中每个路径权值和所对应的最少边数

    时间复杂度$O(n log n)$

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    int n,K,head[200005],tot,allsiz,maxx[200005],root,siz[200005],buc[1000005],cnt,d1[200005],d2[200005],ans=1<<30;
    bool vst[200005];
    struct Edge{
        int to,nxt,w;
    }edge[400005];
    inline int read(){
        int w=0,f=1;
        char ch=0;
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
        while(ch>='0'&&ch<='9')w=(w<<1)+(w<<3)+ch-'0',ch=getchar();
        return w*f;
    }
    void getroot(int k,int fa){
        siz[k]=1,maxx[k]=0;
        for(int i=head[k];i;i=edge[i].nxt){
            int v=edge[i].to;
            if(v!=fa&&!vst[v])getroot(v,k),siz[k]+=siz[v],maxx[k]=max(maxx[k],siz[v]);
        }
        maxx[k]=max(maxx[k],allsiz-siz[k]);
        if(maxx[k]<maxx[root])root=k;
    }
    void getdis(int k,int fa,int w1,int w2){
        if(w1>K)return;
        d1[++cnt]=w1,d2[cnt]=w2;
        for(int i=head[k];i;i=edge[i].nxt){
            int v=edge[i].to;
            if(!vst[v]&&v!=fa)getdis(v,k,edge[i].w+w1,w2+1);
        }
    }
    void calc(int k){
        buc[0]=cnt=0;
        for(int i=head[k];i;i=edge[i].nxt){
            int v=edge[i].to;
            if(!vst[v]){
                int tag=cnt;
                getdis(v,k,edge[i].w,1);
                for(int j=tag+1;j<=cnt;j++)ans=min(ans,buc[K-d1[j]]+d2[j]);
                for(int j=tag+1;j<=cnt;j++)buc[d1[j]]=min(buc[d1[j]],d2[j]);
            }
        }
        for(int i=1;i<=cnt;i++)buc[d1[i]]=0x7f7f7f7f;
    }
    void solve(int k,int s){
        vst[k]=true,calc(k);
        for(int i=head[k];i;i=edge[i].nxt){
            int v=edge[i].to;
            if(vst[v])continue;
            root=0,allsiz=(siz[v]>siz[k]?s-siz[k]:siz[v]),getroot(v,0),solve(root,allsiz);
        }
    }
    int main(){
        maxx[0]=allsiz=n=read(),K=read(),memset(buc,127,sizeof(buc));
        for(int i=1;i<n;i++){
            int u=read()+1,v=read()+1,w=read();
            edge[++tot]=(Edge){v,head[u],w},head[u]=tot,edge[++tot]=(Edge){u,head[v],w},head[v]=tot;
        }
        getroot(1,0),solve(root,allsiz),printf("%d
    ",ans>=n?-1:ans);
        return 0;
    }
    [IOI2011]Race
  • 相关阅读:
    springmvc简介
    AOP的通知类型和注解配置
    word技巧之将目录放置文档的左侧
    【刷题-LeetCode】151 Reverse Words in a String
    【刷题-LeetCode】148 Sort List
    【刷题-LeetCode】150 Evaluate Reverse Polish Notation
    【刷题-LeetCode】147 Insertion Sort List
    【经验总结-博客园】博客园Silence主题模板使用
    【数学】立个flag
    python面试题
  • 原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/14227059.html
Copyright © 2011-2022 走看看