zoukankan      html  css  js  c++  java
  • 【BZOJ2599】Race(点分治)

    【BZOJ2599】Race(点分治)

    题面

    BZOJ权限题,洛谷

    题解

    好久没写过点分治了。。。
    在ppl的帮助下终于想起来了
    orz ppl

    首先回忆一下怎么求有没有正好是(K)的路径
    维护一个表示距离的桶
    对于当前重心,依次插入每棵子树的距离值
    然后检查是否存在即可

    显然加一步,求最短的路径数
    那么,把原来的是否存在的01数组
    改为记录最短路径数的一个(int)数组
    每次插入的时候去取(min)就行了

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long
    #define RG register
    #define MAX 220000
    inline int read()
    {
        RG int x=0,t=1;RG char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    struct Line{int v,next,w;}e[MAX<<1];
    int h[MAX],cnt=1;
    inline void Add(int u,int v,int w){e[cnt]=(Line){v,h[u],w};h[u]=cnt++;}
    int size[MAX],Size,K,n,dep[MAX],dis[MAX],ans;
    bool vis[MAX];
    int mx,root;
    int ext[12000000];
    int S[MAX],top;
    int SS[MAX],Top;
    void Getroot(int u,int ff)
    {
    	size[u]=1;
    	int ret=0;
    	for(int i=h[u];i;i=e[i].next)
    	{
    		int v=e[i].v;
    		if(v==ff||vis[v])continue;
    		Getroot(v,u);
    		ret=max(ret,size[v]);
    		size[u]+=size[v];
    	}
    	ret=max(Size-size[u],ret);
    	if(ret<mx)mx=ret,root=u;
    }
    void Getdep(int u,int ff,int ss,int st)
    {
    	if(ss>K)return;
    	SS[++Top]=S[++top]=u;
    	dep[u]=ss;dis[u]=st;
    	for(int i=h[u];i;i=e[i].next)
    	{
    		int v=e[i].v;
    		if(v==ff||vis[v])continue;
    		Getdep(v,u,ss+e[i].w,st+1);
    	}
    }
    void Calc(int u,int ff,int W)
    {
    	top=0;Getdep(u,ff,W,1);
    	for(int i=1;i<=top;++i)
    	{
    		int dd=dep[S[i]];
    		if(!ext[K-dd])continue;
    		ans=min(ans,dis[S[i]]+ext[K-dd]);
    	}
    	for(int i=1;i<=top;++i)
    	{
    		int dd=dep[S[i]];
    		if(!ext[dd])ext[dd]=dis[S[i]];
    		else ext[dd]=min(ext[dd],dis[S[i]]);
    	}
    }
    void Work(int u)
    {
    	vis[u]=true;Top=0;
    	for(int i=h[u];i;i=e[i].next)
    	{
    		int v=e[i].v;
    		if(vis[v])continue;
    		Calc(v,u,e[i].w);
    	}
    	if(ext[K])ans=min(ans,ext[K]);
    	for(int i=1;i<=Top;++i)ext[dep[SS[i]]]=0;
    	for(int i=h[u];i;i=e[i].next)
    	{
    		int v=e[i].v;
    		if(vis[v])continue;
    		Size=size[v],mx=n;
    		Getroot(v,u);
    		Work(root);
    	}
    }
    int main()
    {
    	n=read();K=read();
    	for(int i=1;i<n;++i)
    	{
    		int u=read()+1,v=read()+1,w=read();
    		Add(u,v,w);Add(v,u,w);
    	}
    	Size=mx=n;Getroot(1,0);
    	ans=1e9;
    	Work(root);
    	printf("%d
    ",ans==1e9?-1:ans);
    	return 0;
    }
    
    
  • 相关阅读:
    【SpringBoot学习笔记】无法解析parent POM——1.5.3.RELEASE
    【WPF学习日记——[DevExpress]】GridControl 行中使用按钮
    【Web学习日记】——C#引用WebService,从配置文件改变引用地址
    【Web学习日记】——在IIS上发布一个WebService
    【WPF学习日记】——Window的DataContext绑定ViewModel
    使用kubectl管理k8s集群
    使用Kubeadm创建k8s集群之节点部署
    使用Kubeadm创建k8s集群之部署规划
    kubernetes运维
    linux常用命令大全
  • 原文地址:https://www.cnblogs.com/cjyyb/p/8473241.html
Copyright © 2011-2022 走看看