• BZOJ 2599: [IOI2011]Race


    点分治模板

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int cnt,n,K,ans,N,root,F_top,last[1000005],sz[1000005],F_[1000005],vis[1000005],F_stack[1000005],G_stack[1000005],F[1000005],G[1000005];
    struct node{
    	int to,next,val;
    }e[1000005];
    void add(int a,int b,int c){
    	e[++cnt].to=b;
    	e[cnt].next=last[a];
    	e[cnt].val=c;
    	last[a]=cnt;
    }
    void find_root(int x,int fa){
    	sz[x]=1,F_[x]=0;
    	for (int i=last[x]; i; i=e[i].next){
    		int V=e[i].to;
    		if (V==fa || vis[V]) continue;
    		find_root(V,x);
    		sz[x]+=sz[V];
    		F_[x]=max(F_[x],sz[V]);
    	}
    	F_[x]=max(F_[x],N-sz[x]);
    	if (F_[x]<F_[root]) root=x;
    }
    void get_dis(int x,int fa,int val,int dep){
    	sz[x]=1;
    	if (val==K) ans=min(ans,dep);
    	if (val<=K) F_stack[++F_top]=val;
    	if (val<=K) F[val]=min(F[val],dep);
    	for (int i=last[x]; i; i=e[i].next){
    		int V=e[i].to;
    		if (vis[V] || V==fa) continue;
    		get_dis(V,x,val+e[i].val,dep+1);
    		sz[x]+=sz[V];
    	}
    }
    void solve(int x){
    	int G_top=0;
    	for (int i=last[x]; i; i=e[i].next){
    		int V=e[i].to;
    		if (vis[V]) continue;
    		F_top=0;
    		get_dis(V,x,e[i].val,1);
    		for (int j=1; j<=F_top; j++) ans=min(ans,F[F_stack[j]]+G[K-F_stack[j]]);
    		for (int j=1; j<=F_top; j++) G[F_stack[j]]=min(G[F_stack[j]],F[F_stack[j]]),F[F_stack[j]]=1e9,G_stack[++G_top]=F_stack[j];
    	}
    	for (int i=1; i<=G_top; i++) G[G_stack[i]]=1e9;
    }
    void divide(int x){
    	vis[x]=1;
    	solve(x);
    	for (int i=last[x]; i; i=e[i].next){
    		int V=e[i].to;
    		if (vis[V]) continue;
    		N=sz[V],root=0;
    		find_root(V,x);
    		divide(root);
    	}
    }
    int main(){
    	scanf("%d%d",&n,&K);
    	for (int i=1; i<n; i++){
    		int x,y,z;
    		scanf("%d%d%d",&x,&y,&z);
    		x++,y++;
    		add(x,y,z);
    		add(y,x,z);
    	}
    	for (int i=1; i<=K; i++) F[i]=G[i]=1e9;
    	ans=1e9;
    	N=n,root=0;
    	F_[0]=1e9;
    	find_root(1,0);
    	divide(root);
    	if (ans!=1e9) printf("%d
    ",ans);
    	else printf("-1
    ");
    	return 0;
    }
    

      

  • 相关阅读:
    leetcode204-统计质数个数之一步步调试超时
    SpringBoot-注解一句话
    算法-总结规律
    kafka-版本变更相关
    异步线程池如何做同步业务
    es-快捷DSL检索手记
    并发学习第七篇——ThreadPoolExecutor
    kafka-consumer端的设计细节
    kafka-producer使用总结
    kafka-topic重要配置分析
  • 原文地址:https://www.cnblogs.com/silenty/p/9783939.html
Copyright © 2020-2023  润新知