ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

BZOJ2599 Race

2021-05-17 15:33:12  阅读:154  来源: 互联网

标签:cnt const int head vis Race maxn BZOJ2599


【题意】

求树上的权值和为k的路径包含最少边数

【分析】

仍然是比较明显的点分治

考虑记录一个l[i]表示权值为i的路径最少边数,得到一个子树的所有点到根的路径,更新答案即可

【代码】

#include<bits/stdc++.h>
using namespace std;
const int maxn=4e5+5;
const int maxm=1e6+5;
const int inf=0x3f3f3f3f;
int n,k;
int head[maxn],tot,vis[maxn];
struct edge
{
    int to,nxt,v;
}e[maxn<<1];
void add(int x,int y,int z)
{
    e[++tot].to=y; e[tot].nxt=head[x]; e[tot].v=z; head[x]=tot;
}
int root,siz[maxn],gsiz,size,f,cnt;
int l[maxm],sum[maxn],tong[maxn];
void findrt(int u,int fa)
{
    siz[u]=1;
    int maxnum=0;
    for(int i=head[u];i;i=e[i].nxt)
    {
        int to=e[i].to;
        if(to==fa || vis[to]) continue;
        findrt(to,u);
        siz[u]+=siz[to];
        maxnum=max(maxnum,siz[to]);
    }
    maxnum=max(maxnum,size-siz[u]);
    if(maxnum<gsiz)
    {
        gsiz=maxnum;
        root=u;
        f=fa;
    }
}
int ans;
void query(int u,int fa,int len,int dep)
{
    if(len>k) return;
    ans=min(ans,dep+l[k-len]);
    tong[++cnt]=len; sum[cnt]=dep;
    for(int i=head[u];i;i=e[i].nxt)
    {
        int to=e[i].to;
        if(to==fa || vis[to]) continue;
        query(to,u,len+e[i].v,dep+1);
    }
}
void solve(int u)
{
    for(int i=head[u];i;i=e[i].nxt)
    {
        int to=e[i].to;
        if(vis[to]) continue;
        int temp=cnt;
        query(to,u,e[i].v,1);
        for(int j=temp+1;j<=cnt;j++)
            l[tong[j]]=min(l[tong[j]],sum[j]);
    }
    for(int i=1;i<=cnt;i++) l[tong[i]]=inf;
    l[0]=0; cnt=0;
}
void divide(int u)
{
    vis[u]=1;
    solve(u);
    int kk=f,t=size;
    for(int i=head[u];i;i=e[i].nxt)
    {
        int to=e[i].to;
        if(vis[to]) continue;
        gsiz=inf;
        root=0;
        size=(to!=kk)?siz[to]:(t-siz[u]);
        findrt(to,0);
        divide(root);
    }
}
int main()
{
//    freopen("a.in","r",stdin);
//    freopen("a.out","w",stdout);
    scanf("%d%d",&n,&k);
    int x,y,z;
    for(int i=1;i<n;i++)
    {
        scanf("%d%d%d",&x,&y,&z);
        x++; y++;
        add(x,y,z); add(y,x,z);
    }
    size=n; gsiz=inf; ans=inf;
    for(int i=1;i<maxm;i++) l[i]=inf;
    findrt(1,0);
    divide(root);
    printf("%d",ans==inf?-1:ans);
    return 0;
}

 

标签:cnt,const,int,head,vis,Race,maxn,BZOJ2599
来源: https://www.cnblogs.com/andylnx/p/14777043.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有