zoukankan      html  css  js  c++  java
  • BZOJ 2599

    http://www.lydsy.com/JudgeOnline/problem.php?id=2599

    就是开一个数组t,t[i]表示权值为i的路径最少边数

    点分治,找到树的重心分成若干子树后,

    得出一棵子树的所有点到根的路径长度x,到根有a条边,用t[k-x]+a更新答案,

    全部查询完后,然后再用所有a更新t[x]

    把一棵树的所有子树搞完后再遍历所有子树恢复原来t数组

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<map>
    #include<algorithm>
    #define FOR(i,s,t) for(register int i=s;i<=t;++i)
    using namespace std;
    const int M=400011,N=200011,MAX=1000011,inf=1e9;
    inline int read(){
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int n,K,cnt,sum,root,ans;
    int t[MAX],last[N],son[N],f[N],dis[N],d[N];
    bool vis[N];
    struct edge{int to,next,v;}e[M];
    inline void insert(int u,int v,int w){
    	e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt;e[cnt].v=w;
    	e[++cnt].to=u;e[cnt].next=last[v];last[v]=cnt;e[cnt].v=w;
    }
    inline void getroot(int x,int fa){
    	son[x]=1;f[x]=0;
    	for(register int i=last[x];i;i=e[i].next)
    		if(e[i].to!=fa&&!vis[e[i].to]){
    			getroot(e[i].to,x);
    			son[x]+=son[e[i].to];
    			f[x]=max(f[x],son[e[i].to]);
    		}
    	f[x]=max(f[x],sum-son[x]);
    	if(f[x]<f[root])root=x;
    }
    inline void cal(int x,int fa){
    	if(dis[x]>K)return;
    	ans=min(ans,d[x]+t[K-dis[x]]);
    	for(register int i=last[x];i;i=e[i].next)
    		if(e[i].to!=fa&&!vis[e[i].to]){
    			d[e[i].to]=d[x]+1;
    			dis[e[i].to]=dis[x]+e[i].v;
    			cal(e[i].to,x);
    		}
    }
    inline void add(int x,int fa,bool flag){
    	if(dis[x]>K)return;
    	if(flag)t[dis[x]]=min(t[dis[x]],d[x]);
    	else t[dis[x]]=inf;
        for(register int i=last[x];i;i=e[i].next)
    		if(e[i].to!=fa&&!vis[e[i].to])
    			add(e[i].to,x,flag);
    }
    inline void work(int x){
    	vis[x]=1;t[0]=0;
    	for(register int i=last[x];i;i=e[i].next)
    		if(!vis[e[i].to]){
    			d[e[i].to]=1;dis[e[i].to]=e[i].v;
    		    cal(e[i].to,0);
    			add(e[i].to,0,1);
    		}
    	for(register int i=last[x];i;i=e[i].next)
    		if(!vis[e[i].to])
    			add(e[i].to,0,0);
    	for(register int i=last[x];i;i=e[i].next)
    		if(!vis[e[i].to]){
    			root=0;sum=son[e[i].to];
    			getroot(e[i].to,0);
    			work(root);
    		}
    }
    int u,v,w;
    int main(){
    	n=read();K=read();
    	FOR(i,1,K)t[i]=n;
    	FOR(i,2,n){
    		u=read(),v=read(),w=read();
    		++u;++v;
    		insert(u,v,w);
    	}
    	ans=sum=f[0]=n;
    	getroot(1,0);
    	work(root);
    	ans!=n?printf("%d
    ",ans):puts("-1");
    	return 0;
    }
    

      

  • 相关阅读:
    1.Spring MVC详解
    servlet的九大内置对象
    Hibernate设置事务的隔离级别
    wamp下php报错session_start(): open(d:/wamp/tmpsess_ku776hvb06ko4lv9d11e7mnfj1, O_RDWR) failed: No such file or directory
    json_decode()相关报错
    wamp下var_dump()相关问题
    es6箭头函数内部判断
    Json数组对象取值
    npm指向淘宝源
    APICloud之封装webApp
  • 原文地址:https://www.cnblogs.com/Stump/p/7979105.html
Copyright © 2011-2022 走看看